Configure AWS Connect Instance Storage

The aws:connect/instanceStorageConfig:InstanceStorageConfig resource, part of the Pulumi AWS provider, configures where Amazon Connect stores specific data types: chat transcripts, contact trace records, media streams, and other interaction artifacts. This guide focuses on three capabilities: S3 storage with KMS encryption, Kinesis Firehose for real-time delivery, and Kinesis Video Streams for media capture.

Storage configurations reference a Connect instance and destination resources that must exist separately. The examples are intentionally small. Combine them with your own Connect instance, S3 buckets, Kinesis streams, and IAM policies.

Store chat transcripts in S3

Contact centers archive chat transcripts to S3 for compliance, analytics, and long-term retention.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.connect.InstanceStorageConfig("example", {
    instanceId: exampleAwsConnectInstance.id,
    resourceType: "CHAT_TRANSCRIPTS",
    storageConfig: {
        s3Config: {
            bucketName: exampleAwsS3Bucket.id,
            bucketPrefix: "example",
        },
        storageType: "S3",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.connect.InstanceStorageConfig("example",
    instance_id=example_aws_connect_instance["id"],
    resource_type="CHAT_TRANSCRIPTS",
    storage_config={
        "s3_config": {
            "bucket_name": example_aws_s3_bucket["id"],
            "bucket_prefix": "example",
        },
        "storage_type": "S3",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/connect"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := connect.NewInstanceStorageConfig(ctx, "example", &connect.InstanceStorageConfigArgs{
			InstanceId:   pulumi.Any(exampleAwsConnectInstance.Id),
			ResourceType: pulumi.String("CHAT_TRANSCRIPTS"),
			StorageConfig: &connect.InstanceStorageConfigStorageConfigArgs{
				S3Config: &connect.InstanceStorageConfigStorageConfigS3ConfigArgs{
					BucketName:   pulumi.Any(exampleAwsS3Bucket.Id),
					BucketPrefix: pulumi.String("example"),
				},
				StorageType: pulumi.String("S3"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.Connect.InstanceStorageConfig("example", new()
    {
        InstanceId = exampleAwsConnectInstance.Id,
        ResourceType = "CHAT_TRANSCRIPTS",
        StorageConfig = new Aws.Connect.Inputs.InstanceStorageConfigStorageConfigArgs
        {
            S3Config = new Aws.Connect.Inputs.InstanceStorageConfigStorageConfigS3ConfigArgs
            {
                BucketName = exampleAwsS3Bucket.Id,
                BucketPrefix = "example",
            },
            StorageType = "S3",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.connect.InstanceStorageConfig;
import com.pulumi.aws.connect.InstanceStorageConfigArgs;
import com.pulumi.aws.connect.inputs.InstanceStorageConfigStorageConfigArgs;
import com.pulumi.aws.connect.inputs.InstanceStorageConfigStorageConfigS3ConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new InstanceStorageConfig("example", InstanceStorageConfigArgs.builder()
            .instanceId(exampleAwsConnectInstance.id())
            .resourceType("CHAT_TRANSCRIPTS")
            .storageConfig(InstanceStorageConfigStorageConfigArgs.builder()
                .s3Config(InstanceStorageConfigStorageConfigS3ConfigArgs.builder()
                    .bucketName(exampleAwsS3Bucket.id())
                    .bucketPrefix("example")
                    .build())
                .storageType("S3")
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:connect:InstanceStorageConfig
    properties:
      instanceId: ${exampleAwsConnectInstance.id}
      resourceType: CHAT_TRANSCRIPTS
      storageConfig:
        s3Config:
          bucketName: ${exampleAwsS3Bucket.id}
          bucketPrefix: example
        storageType: S3

The resourceType property specifies what data to store; here, CHAT_TRANSCRIPTS captures customer chat conversations. The storageType property determines the destination; S3 provides durable, cost-effective storage. The s3Config block sets the bucket and optional prefix for organizing files.

Encrypt chat transcripts with KMS

Sensitive customer conversations require encryption at rest. Adding KMS encryption protects transcripts with customer-managed keys.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.connect.InstanceStorageConfig("example", {
    instanceId: exampleAwsConnectInstance.id,
    resourceType: "CHAT_TRANSCRIPTS",
    storageConfig: {
        s3Config: {
            bucketName: exampleAwsS3Bucket.id,
            bucketPrefix: "example",
            encryptionConfig: {
                encryptionType: "KMS",
                keyId: exampleAwsKmsKey.arn,
            },
        },
        storageType: "S3",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.connect.InstanceStorageConfig("example",
    instance_id=example_aws_connect_instance["id"],
    resource_type="CHAT_TRANSCRIPTS",
    storage_config={
        "s3_config": {
            "bucket_name": example_aws_s3_bucket["id"],
            "bucket_prefix": "example",
            "encryption_config": {
                "encryption_type": "KMS",
                "key_id": example_aws_kms_key["arn"],
            },
        },
        "storage_type": "S3",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/connect"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := connect.NewInstanceStorageConfig(ctx, "example", &connect.InstanceStorageConfigArgs{
			InstanceId:   pulumi.Any(exampleAwsConnectInstance.Id),
			ResourceType: pulumi.String("CHAT_TRANSCRIPTS"),
			StorageConfig: &connect.InstanceStorageConfigStorageConfigArgs{
				S3Config: &connect.InstanceStorageConfigStorageConfigS3ConfigArgs{
					BucketName:   pulumi.Any(exampleAwsS3Bucket.Id),
					BucketPrefix: pulumi.String("example"),
					EncryptionConfig: &connect.InstanceStorageConfigStorageConfigS3ConfigEncryptionConfigArgs{
						EncryptionType: pulumi.String("KMS"),
						KeyId:          pulumi.Any(exampleAwsKmsKey.Arn),
					},
				},
				StorageType: pulumi.String("S3"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.Connect.InstanceStorageConfig("example", new()
    {
        InstanceId = exampleAwsConnectInstance.Id,
        ResourceType = "CHAT_TRANSCRIPTS",
        StorageConfig = new Aws.Connect.Inputs.InstanceStorageConfigStorageConfigArgs
        {
            S3Config = new Aws.Connect.Inputs.InstanceStorageConfigStorageConfigS3ConfigArgs
            {
                BucketName = exampleAwsS3Bucket.Id,
                BucketPrefix = "example",
                EncryptionConfig = new Aws.Connect.Inputs.InstanceStorageConfigStorageConfigS3ConfigEncryptionConfigArgs
                {
                    EncryptionType = "KMS",
                    KeyId = exampleAwsKmsKey.Arn,
                },
            },
            StorageType = "S3",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.connect.InstanceStorageConfig;
import com.pulumi.aws.connect.InstanceStorageConfigArgs;
import com.pulumi.aws.connect.inputs.InstanceStorageConfigStorageConfigArgs;
import com.pulumi.aws.connect.inputs.InstanceStorageConfigStorageConfigS3ConfigArgs;
import com.pulumi.aws.connect.inputs.InstanceStorageConfigStorageConfigS3ConfigEncryptionConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new InstanceStorageConfig("example", InstanceStorageConfigArgs.builder()
            .instanceId(exampleAwsConnectInstance.id())
            .resourceType("CHAT_TRANSCRIPTS")
            .storageConfig(InstanceStorageConfigStorageConfigArgs.builder()
                .s3Config(InstanceStorageConfigStorageConfigS3ConfigArgs.builder()
                    .bucketName(exampleAwsS3Bucket.id())
                    .bucketPrefix("example")
                    .encryptionConfig(InstanceStorageConfigStorageConfigS3ConfigEncryptionConfigArgs.builder()
                        .encryptionType("KMS")
                        .keyId(exampleAwsKmsKey.arn())
                        .build())
                    .build())
                .storageType("S3")
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:connect:InstanceStorageConfig
    properties:
      instanceId: ${exampleAwsConnectInstance.id}
      resourceType: CHAT_TRANSCRIPTS
      storageConfig:
        s3Config:
          bucketName: ${exampleAwsS3Bucket.id}
          bucketPrefix: example
          encryptionConfig:
            encryptionType: KMS
            keyId: ${exampleAwsKmsKey.arn}
        storageType: S3

The encryptionConfig block within s3Config enables KMS encryption. Set encryptionType to KMS and provide your key ARN via keyId. Connect encrypts transcripts before writing to S3, ensuring data protection at rest.

Stream contact trace records to Kinesis Firehose

Real-time analytics pipelines consume contact trace records as they’re generated. Kinesis Firehose delivers these records to destinations like S3, Redshift, or Elasticsearch.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.connect.InstanceStorageConfig("example", {
    instanceId: exampleAwsConnectInstance.id,
    resourceType: "CONTACT_TRACE_RECORDS",
    storageConfig: {
        kinesisFirehoseConfig: {
            firehoseArn: exampleAwsKinesisFirehoseDeliveryStream.arn,
        },
        storageType: "KINESIS_FIREHOSE",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.connect.InstanceStorageConfig("example",
    instance_id=example_aws_connect_instance["id"],
    resource_type="CONTACT_TRACE_RECORDS",
    storage_config={
        "kinesis_firehose_config": {
            "firehose_arn": example_aws_kinesis_firehose_delivery_stream["arn"],
        },
        "storage_type": "KINESIS_FIREHOSE",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/connect"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := connect.NewInstanceStorageConfig(ctx, "example", &connect.InstanceStorageConfigArgs{
			InstanceId:   pulumi.Any(exampleAwsConnectInstance.Id),
			ResourceType: pulumi.String("CONTACT_TRACE_RECORDS"),
			StorageConfig: &connect.InstanceStorageConfigStorageConfigArgs{
				KinesisFirehoseConfig: &connect.InstanceStorageConfigStorageConfigKinesisFirehoseConfigArgs{
					FirehoseArn: pulumi.Any(exampleAwsKinesisFirehoseDeliveryStream.Arn),
				},
				StorageType: pulumi.String("KINESIS_FIREHOSE"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.Connect.InstanceStorageConfig("example", new()
    {
        InstanceId = exampleAwsConnectInstance.Id,
        ResourceType = "CONTACT_TRACE_RECORDS",
        StorageConfig = new Aws.Connect.Inputs.InstanceStorageConfigStorageConfigArgs
        {
            KinesisFirehoseConfig = new Aws.Connect.Inputs.InstanceStorageConfigStorageConfigKinesisFirehoseConfigArgs
            {
                FirehoseArn = exampleAwsKinesisFirehoseDeliveryStream.Arn,
            },
            StorageType = "KINESIS_FIREHOSE",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.connect.InstanceStorageConfig;
import com.pulumi.aws.connect.InstanceStorageConfigArgs;
import com.pulumi.aws.connect.inputs.InstanceStorageConfigStorageConfigArgs;
import com.pulumi.aws.connect.inputs.InstanceStorageConfigStorageConfigKinesisFirehoseConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new InstanceStorageConfig("example", InstanceStorageConfigArgs.builder()
            .instanceId(exampleAwsConnectInstance.id())
            .resourceType("CONTACT_TRACE_RECORDS")
            .storageConfig(InstanceStorageConfigStorageConfigArgs.builder()
                .kinesisFirehoseConfig(InstanceStorageConfigStorageConfigKinesisFirehoseConfigArgs.builder()
                    .firehoseArn(exampleAwsKinesisFirehoseDeliveryStream.arn())
                    .build())
                .storageType("KINESIS_FIREHOSE")
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:connect:InstanceStorageConfig
    properties:
      instanceId: ${exampleAwsConnectInstance.id}
      resourceType: CONTACT_TRACE_RECORDS
      storageConfig:
        kinesisFirehoseConfig:
          firehoseArn: ${exampleAwsKinesisFirehoseDeliveryStream.arn}
        storageType: KINESIS_FIREHOSE

When resourceType is CONTACT_TRACE_RECORDS, Connect sends metadata about each customer interaction (duration, queue time, agent ID) to your analytics pipeline. The kinesisFirehoseConfig block points to your delivery stream ARN, which handles downstream routing and transformation.

Capture media streams with retention and encryption

Video and audio streams from customer interactions can be captured for quality assurance or training. Kinesis Video Streams stores these media files with configurable retention.

import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";

const example = new aws.connect.InstanceStorageConfig("example", {
    instanceId: exampleAwsConnectInstance.id,
    resourceType: "MEDIA_STREAMS",
    storageConfig: {
        kinesisVideoStreamConfig: {
            prefix: "example",
            retentionPeriodHours: 3,
            encryptionConfig: {
                encryptionType: "KMS",
                keyId: exampleAwsKmsKey.arn,
            },
        },
        storageType: "KINESIS_VIDEO_STREAM",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.connect.InstanceStorageConfig("example",
    instance_id=example_aws_connect_instance["id"],
    resource_type="MEDIA_STREAMS",
    storage_config={
        "kinesis_video_stream_config": {
            "prefix": "example",
            "retention_period_hours": 3,
            "encryption_config": {
                "encryption_type": "KMS",
                "key_id": example_aws_kms_key["arn"],
            },
        },
        "storage_type": "KINESIS_VIDEO_STREAM",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/connect"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := connect.NewInstanceStorageConfig(ctx, "example", &connect.InstanceStorageConfigArgs{
			InstanceId:   pulumi.Any(exampleAwsConnectInstance.Id),
			ResourceType: pulumi.String("MEDIA_STREAMS"),
			StorageConfig: &connect.InstanceStorageConfigStorageConfigArgs{
				KinesisVideoStreamConfig: &connect.InstanceStorageConfigStorageConfigKinesisVideoStreamConfigArgs{
					Prefix:               pulumi.String("example"),
					RetentionPeriodHours: pulumi.Int(3),
					EncryptionConfig: &connect.InstanceStorageConfigStorageConfigKinesisVideoStreamConfigEncryptionConfigArgs{
						EncryptionType: pulumi.String("KMS"),
						KeyId:          pulumi.Any(exampleAwsKmsKey.Arn),
					},
				},
				StorageType: pulumi.String("KINESIS_VIDEO_STREAM"),
			},
		})
		if err != nil {
			return err
		}
		return nil
	})
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.Connect.InstanceStorageConfig("example", new()
    {
        InstanceId = exampleAwsConnectInstance.Id,
        ResourceType = "MEDIA_STREAMS",
        StorageConfig = new Aws.Connect.Inputs.InstanceStorageConfigStorageConfigArgs
        {
            KinesisVideoStreamConfig = new Aws.Connect.Inputs.InstanceStorageConfigStorageConfigKinesisVideoStreamConfigArgs
            {
                Prefix = "example",
                RetentionPeriodHours = 3,
                EncryptionConfig = new Aws.Connect.Inputs.InstanceStorageConfigStorageConfigKinesisVideoStreamConfigEncryptionConfigArgs
                {
                    EncryptionType = "KMS",
                    KeyId = exampleAwsKmsKey.Arn,
                },
            },
            StorageType = "KINESIS_VIDEO_STREAM",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.connect.InstanceStorageConfig;
import com.pulumi.aws.connect.InstanceStorageConfigArgs;
import com.pulumi.aws.connect.inputs.InstanceStorageConfigStorageConfigArgs;
import com.pulumi.aws.connect.inputs.InstanceStorageConfigStorageConfigKinesisVideoStreamConfigArgs;
import com.pulumi.aws.connect.inputs.InstanceStorageConfigStorageConfigKinesisVideoStreamConfigEncryptionConfigArgs;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Paths;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var example = new InstanceStorageConfig("example", InstanceStorageConfigArgs.builder()
            .instanceId(exampleAwsConnectInstance.id())
            .resourceType("MEDIA_STREAMS")
            .storageConfig(InstanceStorageConfigStorageConfigArgs.builder()
                .kinesisVideoStreamConfig(InstanceStorageConfigStorageConfigKinesisVideoStreamConfigArgs.builder()
                    .prefix("example")
                    .retentionPeriodHours(3)
                    .encryptionConfig(InstanceStorageConfigStorageConfigKinesisVideoStreamConfigEncryptionConfigArgs.builder()
                        .encryptionType("KMS")
                        .keyId(exampleAwsKmsKey.arn())
                        .build())
                    .build())
                .storageType("KINESIS_VIDEO_STREAM")
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:connect:InstanceStorageConfig
    properties:
      instanceId: ${exampleAwsConnectInstance.id}
      resourceType: MEDIA_STREAMS
      storageConfig:
        kinesisVideoStreamConfig:
          prefix: example
          retentionPeriodHours: 3
          encryptionConfig:
            encryptionType: KMS
            keyId: ${exampleAwsKmsKey.arn}
        storageType: KINESIS_VIDEO_STREAM

The MEDIA_STREAMS resource type captures audio and video from customer calls. The kinesisVideoStreamConfig block sets a prefix for stream naming, retentionPeriodHours for automatic cleanup (here, 3 hours), and encryptionConfig for KMS-based protection. Connect creates video streams automatically using this configuration.

Beyond these examples

These snippets focus on specific storage configuration features: S3 storage with optional encryption and Kinesis Firehose and Video Stream integration. They’re intentionally minimal rather than full contact center deployments.

The examples reference pre-existing infrastructure such as Connect instances, S3 buckets, Kinesis streams, and KMS keys. They focus on configuring storage destinations rather than provisioning the underlying infrastructure.

To keep things focused, common storage patterns are omitted, including:

  • Kinesis Data Stream configuration (storageType: KINESIS_STREAM)
  • Other resource types (CALL_RECORDINGS, ATTACHMENTS, SCHEDULED_REPORTS)
  • IAM role and policy configuration for Connect permissions

These omissions are intentional: the goal is to illustrate how each storage destination is wired, not provide drop-in contact center modules. See the Connect InstanceStorageConfig resource reference for all available configuration options.

Let's configure AWS Connect Instance Storage

Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration & Setup
Which properties are immutable after creation?
Both instanceId and resourceType are immutable. Changing either property forces resource replacement.
What storage types can I configure for my Connect instance?

You can configure four storage types:

  1. Kinesis Firehose - Use kinesisFirehoseConfig with storageType: "KINESIS_FIREHOSE"
  2. Kinesis Stream - Use kinesisStreamConfig with storageType: "KINESIS_STREAM"
  3. Kinesis Video Stream - Use kinesisVideoStreamConfig with storageType: "KINESIS_VIDEO_STREAM"
  4. S3 - Use s3Config with storageType: "S3"
What resource types are valid for storage configuration?
Valid resourceType values include: AGENT_EVENTS, ATTACHMENTS, CALL_RECORDINGS, CHAT_TRANSCRIPTS, CONTACT_EVALUATIONS, CONTACT_TRACE_RECORDS, EMAIL_MESSAGES, MEDIA_STREAMS, REAL_TIME_CONTACT_ANALYSIS_CHAT_SEGMENTS, REAL_TIME_CONTACT_ANALYSIS_SEGMENTS, REAL_TIME_CONTACT_ANALYSIS_VOICE_SEGMENTS, SCHEDULED_REPORTS, and SCREEN_RECORDINGS.
Which resource types work with which storage types?
Examples show: CONTACT_TRACE_RECORDS with Kinesis Firehose/Stream, MEDIA_STREAMS with Kinesis Video Stream, and CHAT_TRANSCRIPTS with S3. Other combinations may be valid but aren’t demonstrated in the examples.
Security & Encryption
How do I enable encryption for stored data?
Add encryptionConfig with encryptionType: "KMS" and keyId (KMS key ARN) to either s3Config or kinesisVideoStreamConfig. Encryption is optional for both storage types.
Import & Management
What's the format for importing an existing storage configuration?
Use the format instance_id:association_id:resource_type with colons as separators. For example: f1288a1f-6193-445a-b47e-af739b2:c1d4e5f6-1b3c-1b3c-1b3c-c1d4e5f6c1d4e5:CHAT_TRANSCRIPTS.

Using a different cloud?

Explore integration guides for other cloud providers: