Configure AWS Chime SDK Media Insights Pipelines

The aws:chimesdkmediapipelines/mediaInsightsPipelineConfiguration:MediaInsightsPipelineConfiguration resource, part of the Pulumi AWS provider, defines a Chime SDK Media Insights Pipeline Configuration that orchestrates audio processing through transcription, analytics, and delivery to various sinks. This guide focuses on four capabilities: transcription with Call Analytics and standard Transcribe processors, real-time alerting on keywords and sentiment, voice analytics for speaker identification, and multi-sink delivery to Kinesis, Lambda, SNS, SQS, and S3.

Configurations reference IAM roles, Kinesis streams, S3 buckets, and other AWS resources that must exist separately. The examples are intentionally small. Combine them with your own IAM policies, stream configurations, and sink destinations.

Stream call analytics to Kinesis

Call analytics pipelines typically start by transcribing audio and streaming insights to Kinesis for real-time processing or downstream analytics.

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

const example = new aws.kinesis.Stream("example", {
    name: "example",
    shardCount: 2,
});
const mediaPipelinesAssumeRole = aws.iam.getPolicyDocument({
    statements: [{
        effect: "Allow",
        principals: [{
            type: "Service",
            identifiers: ["mediapipelines.chime.amazonaws.com"],
        }],
        actions: ["sts:AssumeRole"],
    }],
});
const callAnalyticsRole = new aws.iam.Role("call_analytics_role", {
    name: "CallAnalyticsRole",
    assumeRolePolicy: mediaPipelinesAssumeRole.then(mediaPipelinesAssumeRole => mediaPipelinesAssumeRole.json),
});
const myConfiguration = new aws.chimesdkmediapipelines.MediaInsightsPipelineConfiguration("my_configuration", {
    name: "MyBasicConfiguration",
    resourceAccessRoleArn: callAnalyticsRole.arn,
    elements: [
        {
            type: "AmazonTranscribeCallAnalyticsProcessor",
            amazonTranscribeCallAnalyticsProcessorConfiguration: {
                languageCode: "en-US",
            },
        },
        {
            type: "KinesisDataStreamSink",
            kinesisDataStreamSinkConfiguration: {
                insightsTarget: example.arn,
            },
        },
    ],
    tags: {
        Key1: "Value1",
        Key2: "Value2",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.kinesis.Stream("example",
    name="example",
    shard_count=2)
media_pipelines_assume_role = aws.iam.get_policy_document(statements=[{
    "effect": "Allow",
    "principals": [{
        "type": "Service",
        "identifiers": ["mediapipelines.chime.amazonaws.com"],
    }],
    "actions": ["sts:AssumeRole"],
}])
call_analytics_role = aws.iam.Role("call_analytics_role",
    name="CallAnalyticsRole",
    assume_role_policy=media_pipelines_assume_role.json)
my_configuration = aws.chimesdkmediapipelines.MediaInsightsPipelineConfiguration("my_configuration",
    name="MyBasicConfiguration",
    resource_access_role_arn=call_analytics_role.arn,
    elements=[
        {
            "type": "AmazonTranscribeCallAnalyticsProcessor",
            "amazon_transcribe_call_analytics_processor_configuration": {
                "language_code": "en-US",
            },
        },
        {
            "type": "KinesisDataStreamSink",
            "kinesis_data_stream_sink_configuration": {
                "insights_target": example.arn,
            },
        },
    ],
    tags={
        "Key1": "Value1",
        "Key2": "Value2",
    })
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/chimesdkmediapipelines"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/kinesis"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		example, err := kinesis.NewStream(ctx, "example", &kinesis.StreamArgs{
			Name:       pulumi.String("example"),
			ShardCount: pulumi.Int(2),
		})
		if err != nil {
			return err
		}
		mediaPipelinesAssumeRole, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
			Statements: []iam.GetPolicyDocumentStatement{
				{
					Effect: pulumi.StringRef("Allow"),
					Principals: []iam.GetPolicyDocumentStatementPrincipal{
						{
							Type: "Service",
							Identifiers: []string{
								"mediapipelines.chime.amazonaws.com",
							},
						},
					},
					Actions: []string{
						"sts:AssumeRole",
					},
				},
			},
		}, nil)
		if err != nil {
			return err
		}
		callAnalyticsRole, err := iam.NewRole(ctx, "call_analytics_role", &iam.RoleArgs{
			Name:             pulumi.String("CallAnalyticsRole"),
			AssumeRolePolicy: pulumi.String(mediaPipelinesAssumeRole.Json),
		})
		if err != nil {
			return err
		}
		_, err = chimesdkmediapipelines.NewMediaInsightsPipelineConfiguration(ctx, "my_configuration", &chimesdkmediapipelines.MediaInsightsPipelineConfigurationArgs{
			Name:                  pulumi.String("MyBasicConfiguration"),
			ResourceAccessRoleArn: callAnalyticsRole.Arn,
			Elements: chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArray{
				&chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArgs{
					Type: pulumi.String("AmazonTranscribeCallAnalyticsProcessor"),
					AmazonTranscribeCallAnalyticsProcessorConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationArgs{
						LanguageCode: pulumi.String("en-US"),
					},
				},
				&chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArgs{
					Type: pulumi.String("KinesisDataStreamSink"),
					KinesisDataStreamSinkConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs{
						InsightsTarget: example.Arn,
					},
				},
			},
			Tags: pulumi.StringMap{
				"Key1": pulumi.String("Value1"),
				"Key2": pulumi.String("Value2"),
			},
		})
		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.Kinesis.Stream("example", new()
    {
        Name = "example",
        ShardCount = 2,
    });

    var mediaPipelinesAssumeRole = Aws.Iam.GetPolicyDocument.Invoke(new()
    {
        Statements = new[]
        {
            new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
            {
                Effect = "Allow",
                Principals = new[]
                {
                    new Aws.Iam.Inputs.GetPolicyDocumentStatementPrincipalInputArgs
                    {
                        Type = "Service",
                        Identifiers = new[]
                        {
                            "mediapipelines.chime.amazonaws.com",
                        },
                    },
                },
                Actions = new[]
                {
                    "sts:AssumeRole",
                },
            },
        },
    });

    var callAnalyticsRole = new Aws.Iam.Role("call_analytics_role", new()
    {
        Name = "CallAnalyticsRole",
        AssumeRolePolicy = mediaPipelinesAssumeRole.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
    });

    var myConfiguration = new Aws.ChimeSDKMediaPipelines.MediaInsightsPipelineConfiguration("my_configuration", new()
    {
        Name = "MyBasicConfiguration",
        ResourceAccessRoleArn = callAnalyticsRole.Arn,
        Elements = new[]
        {
            new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementArgs
            {
                Type = "AmazonTranscribeCallAnalyticsProcessor",
                AmazonTranscribeCallAnalyticsProcessorConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationArgs
                {
                    LanguageCode = "en-US",
                },
            },
            new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementArgs
            {
                Type = "KinesisDataStreamSink",
                KinesisDataStreamSinkConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs
                {
                    InsightsTarget = example.Arn,
                },
            },
        },
        Tags = 
        {
            { "Key1", "Value1" },
            { "Key2", "Value2" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.kinesis.Stream;
import com.pulumi.aws.kinesis.StreamArgs;
import com.pulumi.aws.iam.IamFunctions;
import com.pulumi.aws.iam.inputs.GetPolicyDocumentArgs;
import com.pulumi.aws.iam.Role;
import com.pulumi.aws.iam.RoleArgs;
import com.pulumi.aws.chimesdkmediapipelines.MediaInsightsPipelineConfiguration;
import com.pulumi.aws.chimesdkmediapipelines.MediaInsightsPipelineConfigurationArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs;
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 Stream("example", StreamArgs.builder()
            .name("example")
            .shardCount(2)
            .build());

        final var mediaPipelinesAssumeRole = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
            .statements(GetPolicyDocumentStatementArgs.builder()
                .effect("Allow")
                .principals(GetPolicyDocumentStatementPrincipalArgs.builder()
                    .type("Service")
                    .identifiers("mediapipelines.chime.amazonaws.com")
                    .build())
                .actions("sts:AssumeRole")
                .build())
            .build());

        var callAnalyticsRole = new Role("callAnalyticsRole", RoleArgs.builder()
            .name("CallAnalyticsRole")
            .assumeRolePolicy(mediaPipelinesAssumeRole.json())
            .build());

        var myConfiguration = new MediaInsightsPipelineConfiguration("myConfiguration", MediaInsightsPipelineConfigurationArgs.builder()
            .name("MyBasicConfiguration")
            .resourceAccessRoleArn(callAnalyticsRole.arn())
            .elements(            
                MediaInsightsPipelineConfigurationElementArgs.builder()
                    .type("AmazonTranscribeCallAnalyticsProcessor")
                    .amazonTranscribeCallAnalyticsProcessorConfiguration(MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationArgs.builder()
                        .languageCode("en-US")
                        .build())
                    .build(),
                MediaInsightsPipelineConfigurationElementArgs.builder()
                    .type("KinesisDataStreamSink")
                    .kinesisDataStreamSinkConfiguration(MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs.builder()
                        .insightsTarget(example.arn())
                        .build())
                    .build())
            .tags(Map.ofEntries(
                Map.entry("Key1", "Value1"),
                Map.entry("Key2", "Value2")
            ))
            .build());

    }
}
resources:
  myConfiguration:
    type: aws:chimesdkmediapipelines:MediaInsightsPipelineConfiguration
    name: my_configuration
    properties:
      name: MyBasicConfiguration
      resourceAccessRoleArn: ${callAnalyticsRole.arn}
      elements:
        - type: AmazonTranscribeCallAnalyticsProcessor
          amazonTranscribeCallAnalyticsProcessorConfiguration:
            languageCode: en-US
        - type: KinesisDataStreamSink
          kinesisDataStreamSinkConfiguration:
            insightsTarget: ${example.arn}
      tags:
        Key1: Value1
        Key2: Value2
  example:
    type: aws:kinesis:Stream
    properties:
      name: example
      shardCount: 2
  callAnalyticsRole:
    type: aws:iam:Role
    name: call_analytics_role
    properties:
      name: CallAnalyticsRole
      assumeRolePolicy: ${mediaPipelinesAssumeRole.json}
variables:
  mediaPipelinesAssumeRole:
    fn::invoke:
      function: aws:iam:getPolicyDocument
      arguments:
        statements:
          - effect: Allow
            principals:
              - type: Service
                identifiers:
                  - mediapipelines.chime.amazonaws.com
            actions:
              - sts:AssumeRole

The elements array defines the processing pipeline. The AmazonTranscribeCallAnalyticsProcessor transcribes audio in the specified languageCode, while the KinesisDataStreamSink delivers insights to the Kinesis stream ARN. The resourceAccessRoleArn grants the pipeline permissions to invoke Transcribe and write to Kinesis.

Configure call analytics with redaction and post-call processing

Compliance-sensitive applications need PII redaction during transcription and post-call analysis stored in S3 for audit trails.

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

const transcribeAssumeRole = aws.iam.getPolicyDocument({
    statements: [{
        effect: "Allow",
        principals: [{
            type: "Service",
            identifiers: ["transcribe.amazonaws.com"],
        }],
        actions: ["sts:AssumeRole"],
    }],
});
const postCallRole = new aws.iam.Role("post_call_role", {
    name: "PostCallAccessRole",
    assumeRolePolicy: transcribeAssumeRole.then(transcribeAssumeRole => transcribeAssumeRole.json),
});
const myConfiguration = new aws.chimesdkmediapipelines.MediaInsightsPipelineConfiguration("my_configuration", {
    name: "MyCallAnalyticsConfiguration",
    resourceAccessRoleArn: exampleAwsIamRole.arn,
    elements: [
        {
            type: "AmazonTranscribeCallAnalyticsProcessor",
            amazonTranscribeCallAnalyticsProcessorConfiguration: {
                callAnalyticsStreamCategories: [
                    "category_1",
                    "category_2",
                ],
                contentRedactionType: "PII",
                enablePartialResultsStabilization: true,
                filterPartialResults: true,
                languageCode: "en-US",
                languageModelName: "MyLanguageModel",
                partialResultsStability: "high",
                piiEntityTypes: "ADDRESS,BANK_ACCOUNT_NUMBER",
                postCallAnalyticsSettings: {
                    contentRedactionOutput: "redacted",
                    dataAccessRoleArn: postCallRole.arn,
                    outputEncryptionKmsKeyId: "MyKmsKeyId",
                    outputLocation: "s3://MyBucket",
                },
                vocabularyFilterMethod: "mask",
                vocabularyFilterName: "MyVocabularyFilter",
                vocabularyName: "MyVocabulary",
            },
        },
        {
            type: "KinesisDataStreamSink",
            kinesisDataStreamSinkConfiguration: {
                insightsTarget: example.arn,
            },
        },
    ],
});
import pulumi
import pulumi_aws as aws

transcribe_assume_role = aws.iam.get_policy_document(statements=[{
    "effect": "Allow",
    "principals": [{
        "type": "Service",
        "identifiers": ["transcribe.amazonaws.com"],
    }],
    "actions": ["sts:AssumeRole"],
}])
post_call_role = aws.iam.Role("post_call_role",
    name="PostCallAccessRole",
    assume_role_policy=transcribe_assume_role.json)
my_configuration = aws.chimesdkmediapipelines.MediaInsightsPipelineConfiguration("my_configuration",
    name="MyCallAnalyticsConfiguration",
    resource_access_role_arn=example_aws_iam_role["arn"],
    elements=[
        {
            "type": "AmazonTranscribeCallAnalyticsProcessor",
            "amazon_transcribe_call_analytics_processor_configuration": {
                "call_analytics_stream_categories": [
                    "category_1",
                    "category_2",
                ],
                "content_redaction_type": "PII",
                "enable_partial_results_stabilization": True,
                "filter_partial_results": True,
                "language_code": "en-US",
                "language_model_name": "MyLanguageModel",
                "partial_results_stability": "high",
                "pii_entity_types": "ADDRESS,BANK_ACCOUNT_NUMBER",
                "post_call_analytics_settings": {
                    "content_redaction_output": "redacted",
                    "data_access_role_arn": post_call_role.arn,
                    "output_encryption_kms_key_id": "MyKmsKeyId",
                    "output_location": "s3://MyBucket",
                },
                "vocabulary_filter_method": "mask",
                "vocabulary_filter_name": "MyVocabularyFilter",
                "vocabulary_name": "MyVocabulary",
            },
        },
        {
            "type": "KinesisDataStreamSink",
            "kinesis_data_stream_sink_configuration": {
                "insights_target": example["arn"],
            },
        },
    ])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		transcribeAssumeRole, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
			Statements: []iam.GetPolicyDocumentStatement{
				{
					Effect: pulumi.StringRef("Allow"),
					Principals: []iam.GetPolicyDocumentStatementPrincipal{
						{
							Type: "Service",
							Identifiers: []string{
								"transcribe.amazonaws.com",
							},
						},
					},
					Actions: []string{
						"sts:AssumeRole",
					},
				},
			},
		}, nil)
		if err != nil {
			return err
		}
		postCallRole, err := iam.NewRole(ctx, "post_call_role", &iam.RoleArgs{
			Name:             pulumi.String("PostCallAccessRole"),
			AssumeRolePolicy: pulumi.String(transcribeAssumeRole.Json),
		})
		if err != nil {
			return err
		}
		_, err = chimesdkmediapipelines.NewMediaInsightsPipelineConfiguration(ctx, "my_configuration", &chimesdkmediapipelines.MediaInsightsPipelineConfigurationArgs{
			Name:                  pulumi.String("MyCallAnalyticsConfiguration"),
			ResourceAccessRoleArn: pulumi.Any(exampleAwsIamRole.Arn),
			Elements: chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArray{
				&chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArgs{
					Type: pulumi.String("AmazonTranscribeCallAnalyticsProcessor"),
					AmazonTranscribeCallAnalyticsProcessorConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationArgs{
						CallAnalyticsStreamCategories: pulumi.StringArray{
							pulumi.String("category_1"),
							pulumi.String("category_2"),
						},
						ContentRedactionType:              pulumi.String("PII"),
						EnablePartialResultsStabilization: pulumi.Bool(true),
						FilterPartialResults:              pulumi.Bool(true),
						LanguageCode:                      pulumi.String("en-US"),
						LanguageModelName:                 pulumi.String("MyLanguageModel"),
						PartialResultsStability:           pulumi.String("high"),
						PiiEntityTypes:                    pulumi.String("ADDRESS,BANK_ACCOUNT_NUMBER"),
						PostCallAnalyticsSettings: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationPostCallAnalyticsSettingsArgs{
							ContentRedactionOutput:   pulumi.String("redacted"),
							DataAccessRoleArn:        postCallRole.Arn,
							OutputEncryptionKmsKeyId: pulumi.String("MyKmsKeyId"),
							OutputLocation:           pulumi.String("s3://MyBucket"),
						},
						VocabularyFilterMethod: pulumi.String("mask"),
						VocabularyFilterName:   pulumi.String("MyVocabularyFilter"),
						VocabularyName:         pulumi.String("MyVocabulary"),
					},
				},
				&chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArgs{
					Type: pulumi.String("KinesisDataStreamSink"),
					KinesisDataStreamSinkConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs{
						InsightsTarget: pulumi.Any(example.Arn),
					},
				},
			},
		})
		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 transcribeAssumeRole = Aws.Iam.GetPolicyDocument.Invoke(new()
    {
        Statements = new[]
        {
            new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
            {
                Effect = "Allow",
                Principals = new[]
                {
                    new Aws.Iam.Inputs.GetPolicyDocumentStatementPrincipalInputArgs
                    {
                        Type = "Service",
                        Identifiers = new[]
                        {
                            "transcribe.amazonaws.com",
                        },
                    },
                },
                Actions = new[]
                {
                    "sts:AssumeRole",
                },
            },
        },
    });

    var postCallRole = new Aws.Iam.Role("post_call_role", new()
    {
        Name = "PostCallAccessRole",
        AssumeRolePolicy = transcribeAssumeRole.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
    });

    var myConfiguration = new Aws.ChimeSDKMediaPipelines.MediaInsightsPipelineConfiguration("my_configuration", new()
    {
        Name = "MyCallAnalyticsConfiguration",
        ResourceAccessRoleArn = exampleAwsIamRole.Arn,
        Elements = new[]
        {
            new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementArgs
            {
                Type = "AmazonTranscribeCallAnalyticsProcessor",
                AmazonTranscribeCallAnalyticsProcessorConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationArgs
                {
                    CallAnalyticsStreamCategories = new[]
                    {
                        "category_1",
                        "category_2",
                    },
                    ContentRedactionType = "PII",
                    EnablePartialResultsStabilization = true,
                    FilterPartialResults = true,
                    LanguageCode = "en-US",
                    LanguageModelName = "MyLanguageModel",
                    PartialResultsStability = "high",
                    PiiEntityTypes = "ADDRESS,BANK_ACCOUNT_NUMBER",
                    PostCallAnalyticsSettings = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationPostCallAnalyticsSettingsArgs
                    {
                        ContentRedactionOutput = "redacted",
                        DataAccessRoleArn = postCallRole.Arn,
                        OutputEncryptionKmsKeyId = "MyKmsKeyId",
                        OutputLocation = "s3://MyBucket",
                    },
                    VocabularyFilterMethod = "mask",
                    VocabularyFilterName = "MyVocabularyFilter",
                    VocabularyName = "MyVocabulary",
                },
            },
            new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementArgs
            {
                Type = "KinesisDataStreamSink",
                KinesisDataStreamSinkConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs
                {
                    InsightsTarget = example.Arn,
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.iam.IamFunctions;
import com.pulumi.aws.iam.inputs.GetPolicyDocumentArgs;
import com.pulumi.aws.iam.Role;
import com.pulumi.aws.iam.RoleArgs;
import com.pulumi.aws.chimesdkmediapipelines.MediaInsightsPipelineConfiguration;
import com.pulumi.aws.chimesdkmediapipelines.MediaInsightsPipelineConfigurationArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationPostCallAnalyticsSettingsArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs;
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) {
        final var transcribeAssumeRole = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
            .statements(GetPolicyDocumentStatementArgs.builder()
                .effect("Allow")
                .principals(GetPolicyDocumentStatementPrincipalArgs.builder()
                    .type("Service")
                    .identifiers("transcribe.amazonaws.com")
                    .build())
                .actions("sts:AssumeRole")
                .build())
            .build());

        var postCallRole = new Role("postCallRole", RoleArgs.builder()
            .name("PostCallAccessRole")
            .assumeRolePolicy(transcribeAssumeRole.json())
            .build());

        var myConfiguration = new MediaInsightsPipelineConfiguration("myConfiguration", MediaInsightsPipelineConfigurationArgs.builder()
            .name("MyCallAnalyticsConfiguration")
            .resourceAccessRoleArn(exampleAwsIamRole.arn())
            .elements(            
                MediaInsightsPipelineConfigurationElementArgs.builder()
                    .type("AmazonTranscribeCallAnalyticsProcessor")
                    .amazonTranscribeCallAnalyticsProcessorConfiguration(MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationArgs.builder()
                        .callAnalyticsStreamCategories(                        
                            "category_1",
                            "category_2")
                        .contentRedactionType("PII")
                        .enablePartialResultsStabilization(true)
                        .filterPartialResults(true)
                        .languageCode("en-US")
                        .languageModelName("MyLanguageModel")
                        .partialResultsStability("high")
                        .piiEntityTypes("ADDRESS,BANK_ACCOUNT_NUMBER")
                        .postCallAnalyticsSettings(MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationPostCallAnalyticsSettingsArgs.builder()
                            .contentRedactionOutput("redacted")
                            .dataAccessRoleArn(postCallRole.arn())
                            .outputEncryptionKmsKeyId("MyKmsKeyId")
                            .outputLocation("s3://MyBucket")
                            .build())
                        .vocabularyFilterMethod("mask")
                        .vocabularyFilterName("MyVocabularyFilter")
                        .vocabularyName("MyVocabulary")
                        .build())
                    .build(),
                MediaInsightsPipelineConfigurationElementArgs.builder()
                    .type("KinesisDataStreamSink")
                    .kinesisDataStreamSinkConfiguration(MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs.builder()
                        .insightsTarget(example.arn())
                        .build())
                    .build())
            .build());

    }
}
resources:
  myConfiguration:
    type: aws:chimesdkmediapipelines:MediaInsightsPipelineConfiguration
    name: my_configuration
    properties:
      name: MyCallAnalyticsConfiguration
      resourceAccessRoleArn: ${exampleAwsIamRole.arn}
      elements:
        - type: AmazonTranscribeCallAnalyticsProcessor
          amazonTranscribeCallAnalyticsProcessorConfiguration:
            callAnalyticsStreamCategories:
              - category_1
              - category_2
            contentRedactionType: PII
            enablePartialResultsStabilization: true
            filterPartialResults: true
            languageCode: en-US
            languageModelName: MyLanguageModel
            partialResultsStability: high
            piiEntityTypes: ADDRESS,BANK_ACCOUNT_NUMBER
            postCallAnalyticsSettings:
              contentRedactionOutput: redacted
              dataAccessRoleArn: ${postCallRole.arn}
              outputEncryptionKmsKeyId: MyKmsKeyId
              outputLocation: s3://MyBucket
            vocabularyFilterMethod: mask
            vocabularyFilterName: MyVocabularyFilter
            vocabularyName: MyVocabulary
        - type: KinesisDataStreamSink
          kinesisDataStreamSinkConfiguration:
            insightsTarget: ${example.arn}
  postCallRole:
    type: aws:iam:Role
    name: post_call_role
    properties:
      name: PostCallAccessRole
      assumeRolePolicy: ${transcribeAssumeRole.json}
variables:
  transcribeAssumeRole:
    fn::invoke:
      function: aws:iam:getPolicyDocument
      arguments:
        statements:
          - effect: Allow
            principals:
              - type: Service
                identifiers:
                  - transcribe.amazonaws.com
            actions:
              - sts:AssumeRole

The contentRedactionType and piiEntityTypes properties control what sensitive data gets redacted during transcription. The postCallAnalyticsSettings block configures where post-call analytics are stored (outputLocation), which IAM role Transcribe uses to write results (dataAccessRoleArn), and how results are encrypted (outputEncryptionKmsKeyId). The vocabularyFilterMethod determines whether filtered words are masked or removed.

Trigger alerts on keywords and sentiment

Contact centers monitor calls for specific keywords, negative sentiment, or detected issues to route escalations or trigger supervisor notifications.

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

const myConfiguration = new aws.chimesdkmediapipelines.MediaInsightsPipelineConfiguration("my_configuration", {
    name: "MyRealTimeAlertConfiguration",
    resourceAccessRoleArn: callAnalyticsRole.arn,
    elements: [
        {
            type: "AmazonTranscribeCallAnalyticsProcessor",
            amazonTranscribeCallAnalyticsProcessorConfiguration: {
                languageCode: "en-US",
            },
        },
        {
            type: "KinesisDataStreamSink",
            kinesisDataStreamSinkConfiguration: {
                insightsTarget: example.arn,
            },
        },
    ],
    realTimeAlertConfiguration: {
        disabled: false,
        rules: [
            {
                type: "IssueDetection",
                issueDetectionConfiguration: {
                    ruleName: "MyIssueDetectionRule",
                },
            },
            {
                type: "KeywordMatch",
                keywordMatchConfiguration: {
                    keywords: [
                        "keyword1",
                        "keyword2",
                    ],
                    negate: false,
                    ruleName: "MyKeywordMatchRule",
                },
            },
            {
                type: "Sentiment",
                sentimentConfiguration: {
                    ruleName: "MySentimentRule",
                    sentimentType: "NEGATIVE",
                    timePeriod: 60,
                },
            },
        ],
    },
});
import pulumi
import pulumi_aws as aws

my_configuration = aws.chimesdkmediapipelines.MediaInsightsPipelineConfiguration("my_configuration",
    name="MyRealTimeAlertConfiguration",
    resource_access_role_arn=call_analytics_role["arn"],
    elements=[
        {
            "type": "AmazonTranscribeCallAnalyticsProcessor",
            "amazon_transcribe_call_analytics_processor_configuration": {
                "language_code": "en-US",
            },
        },
        {
            "type": "KinesisDataStreamSink",
            "kinesis_data_stream_sink_configuration": {
                "insights_target": example["arn"],
            },
        },
    ],
    real_time_alert_configuration={
        "disabled": False,
        "rules": [
            {
                "type": "IssueDetection",
                "issue_detection_configuration": {
                    "rule_name": "MyIssueDetectionRule",
                },
            },
            {
                "type": "KeywordMatch",
                "keyword_match_configuration": {
                    "keywords": [
                        "keyword1",
                        "keyword2",
                    ],
                    "negate": False,
                    "rule_name": "MyKeywordMatchRule",
                },
            },
            {
                "type": "Sentiment",
                "sentiment_configuration": {
                    "rule_name": "MySentimentRule",
                    "sentiment_type": "NEGATIVE",
                    "time_period": 60,
                },
            },
        ],
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := chimesdkmediapipelines.NewMediaInsightsPipelineConfiguration(ctx, "my_configuration", &chimesdkmediapipelines.MediaInsightsPipelineConfigurationArgs{
			Name:                  pulumi.String("MyRealTimeAlertConfiguration"),
			ResourceAccessRoleArn: pulumi.Any(callAnalyticsRole.Arn),
			Elements: chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArray{
				&chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArgs{
					Type: pulumi.String("AmazonTranscribeCallAnalyticsProcessor"),
					AmazonTranscribeCallAnalyticsProcessorConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationArgs{
						LanguageCode: pulumi.String("en-US"),
					},
				},
				&chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArgs{
					Type: pulumi.String("KinesisDataStreamSink"),
					KinesisDataStreamSinkConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs{
						InsightsTarget: pulumi.Any(example.Arn),
					},
				},
			},
			RealTimeAlertConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationArgs{
				Disabled: pulumi.Bool(false),
				Rules: chimesdkmediapipelines.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleArray{
					&chimesdkmediapipelines.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleArgs{
						Type: pulumi.String("IssueDetection"),
						IssueDetectionConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleIssueDetectionConfigurationArgs{
							RuleName: pulumi.String("MyIssueDetectionRule"),
						},
					},
					&chimesdkmediapipelines.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleArgs{
						Type: pulumi.String("KeywordMatch"),
						KeywordMatchConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleKeywordMatchConfigurationArgs{
							Keywords: pulumi.StringArray{
								pulumi.String("keyword1"),
								pulumi.String("keyword2"),
							},
							Negate:   pulumi.Bool(false),
							RuleName: pulumi.String("MyKeywordMatchRule"),
						},
					},
					&chimesdkmediapipelines.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleArgs{
						Type: pulumi.String("Sentiment"),
						SentimentConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleSentimentConfigurationArgs{
							RuleName:      pulumi.String("MySentimentRule"),
							SentimentType: pulumi.String("NEGATIVE"),
							TimePeriod:    pulumi.Int(60),
						},
					},
				},
			},
		})
		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 myConfiguration = new Aws.ChimeSDKMediaPipelines.MediaInsightsPipelineConfiguration("my_configuration", new()
    {
        Name = "MyRealTimeAlertConfiguration",
        ResourceAccessRoleArn = callAnalyticsRole.Arn,
        Elements = new[]
        {
            new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementArgs
            {
                Type = "AmazonTranscribeCallAnalyticsProcessor",
                AmazonTranscribeCallAnalyticsProcessorConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationArgs
                {
                    LanguageCode = "en-US",
                },
            },
            new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementArgs
            {
                Type = "KinesisDataStreamSink",
                KinesisDataStreamSinkConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs
                {
                    InsightsTarget = example.Arn,
                },
            },
        },
        RealTimeAlertConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationArgs
        {
            Disabled = false,
            Rules = new[]
            {
                new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleArgs
                {
                    Type = "IssueDetection",
                    IssueDetectionConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleIssueDetectionConfigurationArgs
                    {
                        RuleName = "MyIssueDetectionRule",
                    },
                },
                new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleArgs
                {
                    Type = "KeywordMatch",
                    KeywordMatchConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleKeywordMatchConfigurationArgs
                    {
                        Keywords = new[]
                        {
                            "keyword1",
                            "keyword2",
                        },
                        Negate = false,
                        RuleName = "MyKeywordMatchRule",
                    },
                },
                new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleArgs
                {
                    Type = "Sentiment",
                    SentimentConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleSentimentConfigurationArgs
                    {
                        RuleName = "MySentimentRule",
                        SentimentType = "NEGATIVE",
                        TimePeriod = 60,
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.chimesdkmediapipelines.MediaInsightsPipelineConfiguration;
import com.pulumi.aws.chimesdkmediapipelines.MediaInsightsPipelineConfigurationArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationRealTimeAlertConfigurationArgs;
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 myConfiguration = new MediaInsightsPipelineConfiguration("myConfiguration", MediaInsightsPipelineConfigurationArgs.builder()
            .name("MyRealTimeAlertConfiguration")
            .resourceAccessRoleArn(callAnalyticsRole.arn())
            .elements(            
                MediaInsightsPipelineConfigurationElementArgs.builder()
                    .type("AmazonTranscribeCallAnalyticsProcessor")
                    .amazonTranscribeCallAnalyticsProcessorConfiguration(MediaInsightsPipelineConfigurationElementAmazonTranscribeCallAnalyticsProcessorConfigurationArgs.builder()
                        .languageCode("en-US")
                        .build())
                    .build(),
                MediaInsightsPipelineConfigurationElementArgs.builder()
                    .type("KinesisDataStreamSink")
                    .kinesisDataStreamSinkConfiguration(MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs.builder()
                        .insightsTarget(example.arn())
                        .build())
                    .build())
            .realTimeAlertConfiguration(MediaInsightsPipelineConfigurationRealTimeAlertConfigurationArgs.builder()
                .disabled(false)
                .rules(                
                    MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleArgs.builder()
                        .type("IssueDetection")
                        .issueDetectionConfiguration(MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleIssueDetectionConfigurationArgs.builder()
                            .ruleName("MyIssueDetectionRule")
                            .build())
                        .build(),
                    MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleArgs.builder()
                        .type("KeywordMatch")
                        .keywordMatchConfiguration(MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleKeywordMatchConfigurationArgs.builder()
                            .keywords(                            
                                "keyword1",
                                "keyword2")
                            .negate(false)
                            .ruleName("MyKeywordMatchRule")
                            .build())
                        .build(),
                    MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleArgs.builder()
                        .type("Sentiment")
                        .sentimentConfiguration(MediaInsightsPipelineConfigurationRealTimeAlertConfigurationRuleSentimentConfigurationArgs.builder()
                            .ruleName("MySentimentRule")
                            .sentimentType("NEGATIVE")
                            .timePeriod(60)
                            .build())
                        .build())
                .build())
            .build());

    }
}
resources:
  myConfiguration:
    type: aws:chimesdkmediapipelines:MediaInsightsPipelineConfiguration
    name: my_configuration
    properties:
      name: MyRealTimeAlertConfiguration
      resourceAccessRoleArn: ${callAnalyticsRole.arn}
      elements:
        - type: AmazonTranscribeCallAnalyticsProcessor
          amazonTranscribeCallAnalyticsProcessorConfiguration:
            languageCode: en-US
        - type: KinesisDataStreamSink
          kinesisDataStreamSinkConfiguration:
            insightsTarget: ${example.arn}
      realTimeAlertConfiguration:
        disabled: false
        rules:
          - type: IssueDetection
            issueDetectionConfiguration:
              ruleName: MyIssueDetectionRule
          - type: KeywordMatch
            keywordMatchConfiguration:
              keywords:
                - keyword1
                - keyword2
              negate: false
              ruleName: MyKeywordMatchRule
          - type: Sentiment
            sentimentConfiguration:
              ruleName: MySentimentRule
              sentimentType: NEGATIVE
              timePeriod: 60

The realTimeAlertConfiguration defines rules that send EventBridge notifications when conditions are met. KeywordMatch rules trigger on specific words, Sentiment rules fire when tone matches the sentimentType for a given timePeriod, and IssueDetection rules identify problematic interactions. Each rule type requires a ruleName for identification in EventBridge events.

Analyze voice characteristics and route to multiple sinks

Voice analytics extracts speaker identification and tone analysis, often routing results to multiple destinations for different downstream consumers.

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

const myConfiguration = new aws.chimesdkmediapipelines.MediaInsightsPipelineConfiguration("my_configuration", {
    name: "MyVoiceAnalyticsConfiguration",
    resourceAccessRoleArn: example.arn,
    elements: [
        {
            type: "VoiceAnalyticsProcessor",
            voiceAnalyticsProcessorConfiguration: {
                speakerSearchStatus: "Enabled",
                voiceToneAnalysisStatus: "Enabled",
            },
        },
        {
            type: "LambdaFunctionSink",
            lambdaFunctionSinkConfiguration: {
                insightsTarget: "arn:aws:lambda:us-west-2:1111111111:function:MyFunction",
            },
        },
        {
            type: "SnsTopicSink",
            snsTopicSinkConfiguration: {
                insightsTarget: "arn:aws:sns:us-west-2:1111111111:topic/MyTopic",
            },
        },
        {
            type: "SqsQueueSink",
            sqsQueueSinkConfiguration: {
                insightsTarget: "arn:aws:sqs:us-west-2:1111111111:queue/MyQueue",
            },
        },
        {
            type: "KinesisDataStreamSink",
            kinesisDataStreamSinkConfiguration: {
                insightsTarget: test.arn,
            },
        },
    ],
});
import pulumi
import pulumi_aws as aws

my_configuration = aws.chimesdkmediapipelines.MediaInsightsPipelineConfiguration("my_configuration",
    name="MyVoiceAnalyticsConfiguration",
    resource_access_role_arn=example["arn"],
    elements=[
        {
            "type": "VoiceAnalyticsProcessor",
            "voice_analytics_processor_configuration": {
                "speaker_search_status": "Enabled",
                "voice_tone_analysis_status": "Enabled",
            },
        },
        {
            "type": "LambdaFunctionSink",
            "lambda_function_sink_configuration": {
                "insights_target": "arn:aws:lambda:us-west-2:1111111111:function:MyFunction",
            },
        },
        {
            "type": "SnsTopicSink",
            "sns_topic_sink_configuration": {
                "insights_target": "arn:aws:sns:us-west-2:1111111111:topic/MyTopic",
            },
        },
        {
            "type": "SqsQueueSink",
            "sqs_queue_sink_configuration": {
                "insights_target": "arn:aws:sqs:us-west-2:1111111111:queue/MyQueue",
            },
        },
        {
            "type": "KinesisDataStreamSink",
            "kinesis_data_stream_sink_configuration": {
                "insights_target": test["arn"],
            },
        },
    ])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := chimesdkmediapipelines.NewMediaInsightsPipelineConfiguration(ctx, "my_configuration", &chimesdkmediapipelines.MediaInsightsPipelineConfigurationArgs{
			Name:                  pulumi.String("MyVoiceAnalyticsConfiguration"),
			ResourceAccessRoleArn: pulumi.Any(example.Arn),
			Elements: chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArray{
				&chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArgs{
					Type: pulumi.String("VoiceAnalyticsProcessor"),
					VoiceAnalyticsProcessorConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementVoiceAnalyticsProcessorConfigurationArgs{
						SpeakerSearchStatus:     pulumi.String("Enabled"),
						VoiceToneAnalysisStatus: pulumi.String("Enabled"),
					},
				},
				&chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArgs{
					Type: pulumi.String("LambdaFunctionSink"),
					LambdaFunctionSinkConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementLambdaFunctionSinkConfigurationArgs{
						InsightsTarget: pulumi.String("arn:aws:lambda:us-west-2:1111111111:function:MyFunction"),
					},
				},
				&chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArgs{
					Type: pulumi.String("SnsTopicSink"),
					SnsTopicSinkConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementSnsTopicSinkConfigurationArgs{
						InsightsTarget: pulumi.String("arn:aws:sns:us-west-2:1111111111:topic/MyTopic"),
					},
				},
				&chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArgs{
					Type: pulumi.String("SqsQueueSink"),
					SqsQueueSinkConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementSqsQueueSinkConfigurationArgs{
						InsightsTarget: pulumi.String("arn:aws:sqs:us-west-2:1111111111:queue/MyQueue"),
					},
				},
				&chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArgs{
					Type: pulumi.String("KinesisDataStreamSink"),
					KinesisDataStreamSinkConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs{
						InsightsTarget: pulumi.Any(test.Arn),
					},
				},
			},
		})
		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 myConfiguration = new Aws.ChimeSDKMediaPipelines.MediaInsightsPipelineConfiguration("my_configuration", new()
    {
        Name = "MyVoiceAnalyticsConfiguration",
        ResourceAccessRoleArn = example.Arn,
        Elements = new[]
        {
            new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementArgs
            {
                Type = "VoiceAnalyticsProcessor",
                VoiceAnalyticsProcessorConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementVoiceAnalyticsProcessorConfigurationArgs
                {
                    SpeakerSearchStatus = "Enabled",
                    VoiceToneAnalysisStatus = "Enabled",
                },
            },
            new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementArgs
            {
                Type = "LambdaFunctionSink",
                LambdaFunctionSinkConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementLambdaFunctionSinkConfigurationArgs
                {
                    InsightsTarget = "arn:aws:lambda:us-west-2:1111111111:function:MyFunction",
                },
            },
            new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementArgs
            {
                Type = "SnsTopicSink",
                SnsTopicSinkConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementSnsTopicSinkConfigurationArgs
                {
                    InsightsTarget = "arn:aws:sns:us-west-2:1111111111:topic/MyTopic",
                },
            },
            new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementArgs
            {
                Type = "SqsQueueSink",
                SqsQueueSinkConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementSqsQueueSinkConfigurationArgs
                {
                    InsightsTarget = "arn:aws:sqs:us-west-2:1111111111:queue/MyQueue",
                },
            },
            new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementArgs
            {
                Type = "KinesisDataStreamSink",
                KinesisDataStreamSinkConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs
                {
                    InsightsTarget = test.Arn,
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.chimesdkmediapipelines.MediaInsightsPipelineConfiguration;
import com.pulumi.aws.chimesdkmediapipelines.MediaInsightsPipelineConfigurationArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementVoiceAnalyticsProcessorConfigurationArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementLambdaFunctionSinkConfigurationArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementSnsTopicSinkConfigurationArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementSqsQueueSinkConfigurationArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs;
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 myConfiguration = new MediaInsightsPipelineConfiguration("myConfiguration", MediaInsightsPipelineConfigurationArgs.builder()
            .name("MyVoiceAnalyticsConfiguration")
            .resourceAccessRoleArn(example.arn())
            .elements(            
                MediaInsightsPipelineConfigurationElementArgs.builder()
                    .type("VoiceAnalyticsProcessor")
                    .voiceAnalyticsProcessorConfiguration(MediaInsightsPipelineConfigurationElementVoiceAnalyticsProcessorConfigurationArgs.builder()
                        .speakerSearchStatus("Enabled")
                        .voiceToneAnalysisStatus("Enabled")
                        .build())
                    .build(),
                MediaInsightsPipelineConfigurationElementArgs.builder()
                    .type("LambdaFunctionSink")
                    .lambdaFunctionSinkConfiguration(MediaInsightsPipelineConfigurationElementLambdaFunctionSinkConfigurationArgs.builder()
                        .insightsTarget("arn:aws:lambda:us-west-2:1111111111:function:MyFunction")
                        .build())
                    .build(),
                MediaInsightsPipelineConfigurationElementArgs.builder()
                    .type("SnsTopicSink")
                    .snsTopicSinkConfiguration(MediaInsightsPipelineConfigurationElementSnsTopicSinkConfigurationArgs.builder()
                        .insightsTarget("arn:aws:sns:us-west-2:1111111111:topic/MyTopic")
                        .build())
                    .build(),
                MediaInsightsPipelineConfigurationElementArgs.builder()
                    .type("SqsQueueSink")
                    .sqsQueueSinkConfiguration(MediaInsightsPipelineConfigurationElementSqsQueueSinkConfigurationArgs.builder()
                        .insightsTarget("arn:aws:sqs:us-west-2:1111111111:queue/MyQueue")
                        .build())
                    .build(),
                MediaInsightsPipelineConfigurationElementArgs.builder()
                    .type("KinesisDataStreamSink")
                    .kinesisDataStreamSinkConfiguration(MediaInsightsPipelineConfigurationElementKinesisDataStreamSinkConfigurationArgs.builder()
                        .insightsTarget(test.arn())
                        .build())
                    .build())
            .build());

    }
}
resources:
  myConfiguration:
    type: aws:chimesdkmediapipelines:MediaInsightsPipelineConfiguration
    name: my_configuration
    properties:
      name: MyVoiceAnalyticsConfiguration
      resourceAccessRoleArn: ${example.arn}
      elements:
        - type: VoiceAnalyticsProcessor
          voiceAnalyticsProcessorConfiguration:
            speakerSearchStatus: Enabled
            voiceToneAnalysisStatus: Enabled
        - type: LambdaFunctionSink
          lambdaFunctionSinkConfiguration:
            insightsTarget: arn:aws:lambda:us-west-2:1111111111:function:MyFunction
        - type: SnsTopicSink
          snsTopicSinkConfiguration:
            insightsTarget: arn:aws:sns:us-west-2:1111111111:topic/MyTopic
        - type: SqsQueueSink
          sqsQueueSinkConfiguration:
            insightsTarget: arn:aws:sqs:us-west-2:1111111111:queue/MyQueue
        - type: KinesisDataStreamSink
          kinesisDataStreamSinkConfiguration:
            insightsTarget: ${test.arn}

The VoiceAnalyticsProcessor enables speakerSearchStatus and voiceToneAnalysisStatus to identify speakers and analyze emotional tone. Results can flow to multiple sinks simultaneously: LambdaFunctionSink for custom processing, SnsTopicSink for notifications, SqsQueueSink for queued processing, and KinesisDataStreamSink for streaming analytics. Each sink’s insightsTarget points to the destination ARN.

Record media to S3 for archival

Compliance requirements often mandate storing raw audio recordings alongside analytics for audit and quality assurance purposes.

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

const myConfiguration = new aws.chimesdkmediapipelines.MediaInsightsPipelineConfiguration("my_configuration", {
    name: "MyS3RecordingConfiguration",
    resourceAccessRoleArn: example.arn,
    elements: [{
        type: "S3RecordingSink",
        s3RecordingSinkConfiguration: {
            destination: "arn:aws:s3:::MyBucket",
        },
    }],
});
import pulumi
import pulumi_aws as aws

my_configuration = aws.chimesdkmediapipelines.MediaInsightsPipelineConfiguration("my_configuration",
    name="MyS3RecordingConfiguration",
    resource_access_role_arn=example["arn"],
    elements=[{
        "type": "S3RecordingSink",
        "s3_recording_sink_configuration": {
            "destination": "arn:aws:s3:::MyBucket",
        },
    }])
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := chimesdkmediapipelines.NewMediaInsightsPipelineConfiguration(ctx, "my_configuration", &chimesdkmediapipelines.MediaInsightsPipelineConfigurationArgs{
			Name:                  pulumi.String("MyS3RecordingConfiguration"),
			ResourceAccessRoleArn: pulumi.Any(example.Arn),
			Elements: chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArray{
				&chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementArgs{
					Type: pulumi.String("S3RecordingSink"),
					S3RecordingSinkConfiguration: &chimesdkmediapipelines.MediaInsightsPipelineConfigurationElementS3RecordingSinkConfigurationArgs{
						Destination: pulumi.String("arn:aws:s3:::MyBucket"),
					},
				},
			},
		})
		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 myConfiguration = new Aws.ChimeSDKMediaPipelines.MediaInsightsPipelineConfiguration("my_configuration", new()
    {
        Name = "MyS3RecordingConfiguration",
        ResourceAccessRoleArn = example.Arn,
        Elements = new[]
        {
            new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementArgs
            {
                Type = "S3RecordingSink",
                S3RecordingSinkConfiguration = new Aws.ChimeSDKMediaPipelines.Inputs.MediaInsightsPipelineConfigurationElementS3RecordingSinkConfigurationArgs
                {
                    Destination = "arn:aws:s3:::MyBucket",
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.chimesdkmediapipelines.MediaInsightsPipelineConfiguration;
import com.pulumi.aws.chimesdkmediapipelines.MediaInsightsPipelineConfigurationArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementArgs;
import com.pulumi.aws.chimesdkmediapipelines.inputs.MediaInsightsPipelineConfigurationElementS3RecordingSinkConfigurationArgs;
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 myConfiguration = new MediaInsightsPipelineConfiguration("myConfiguration", MediaInsightsPipelineConfigurationArgs.builder()
            .name("MyS3RecordingConfiguration")
            .resourceAccessRoleArn(example.arn())
            .elements(MediaInsightsPipelineConfigurationElementArgs.builder()
                .type("S3RecordingSink")
                .s3RecordingSinkConfiguration(MediaInsightsPipelineConfigurationElementS3RecordingSinkConfigurationArgs.builder()
                    .destination("arn:aws:s3:::MyBucket")
                    .build())
                .build())
            .build());

    }
}
resources:
  myConfiguration:
    type: aws:chimesdkmediapipelines:MediaInsightsPipelineConfiguration
    name: my_configuration
    properties:
      name: MyS3RecordingConfiguration
      resourceAccessRoleArn: ${example.arn}
      elements:
        - type: S3RecordingSink
          s3RecordingSinkConfiguration:
            destination: arn:aws:s3:::MyBucket

The S3RecordingSink writes raw media files to the specified S3 bucket. Unlike processor elements, recording sinks don’t transform data; they archive the original audio stream. The destination property accepts an S3 bucket ARN.

Beyond these examples

These snippets focus on specific pipeline configuration features: transcription processors (Call Analytics and standard Transcribe), voice analytics and real-time alerting, and multi-sink delivery (Kinesis, Lambda, SNS, SQS, S3). They’re intentionally minimal rather than full call analytics solutions.

The examples may reference pre-existing infrastructure such as Kinesis streams, S3 buckets, Lambda functions, SNS topics, SQS queues, IAM roles with appropriate policies for processors and sinks, Transcribe custom vocabularies and language models, and KMS keys for encryption. They focus on configuring the pipeline rather than provisioning everything around it.

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

  • IAM policy details for resource access roles
  • Kinesis stream configuration (shard count, retention)
  • S3 bucket policies and encryption settings
  • EventBridge rule configuration for alert routing

These omissions are intentional: the goal is to illustrate how each pipeline feature is wired, not provide drop-in call analytics modules. See the Media Insights Pipeline Configuration resource reference for all available configuration options.

Let's configure AWS Chime SDK Media Insights Pipelines

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration Basics
What are the required fields for a Media Insights Pipeline Configuration?
You must provide elements (processors and sinks), name, resourceAccessRoleArn, and region. The region defaults to your provider configuration if not specified.
What IAM permissions does my resource access role need?
The required IAM policies vary based on which processors you configure. Consult the AWS Call analytics resource access role documentation to choose appropriate policies for your selected processors.
Processors & Sinks
What processor types are available?
Three processor types are available: AmazonTranscribeCallAnalyticsProcessor for call analytics with sentiment and issue detection, AmazonTranscribeProcessor for standard transcription, and VoiceAnalyticsProcessor for speaker search and voice tone analysis.
What's the difference between AmazonTranscribeCallAnalyticsProcessor and AmazonTranscribeProcessor?
AmazonTranscribeCallAnalyticsProcessor includes call analytics features like sentiment analysis, issue detection, and post-call analytics. AmazonTranscribeProcessor provides standard transcription without these analytics capabilities.
What sink types can I use to deliver insights data?
Five sink types are available: KinesisDataStreamSink, LambdaFunctionSink, SnsTopicSink, SqsQueueSink, and S3RecordingSink.
Can I configure multiple sinks in one pipeline?
Yes, you can use multiple sinks simultaneously. The voice analytics example demonstrates a configuration with Lambda, SNS, SQS, and Kinesis sinks all active at once.
Real-time Alerts
What types of real-time alert rules can I configure?
Three rule types are available: IssueDetection for identifying issues, KeywordMatch for detecting specific keywords, and Sentiment for monitoring sentiment changes over time.
How do I enable real-time alerts?
Configure realTimeAlertConfiguration with disabled set to false and define your rules array with the desired rule types (IssueDetection, KeywordMatch, or Sentiment).
Advanced Features
How do I configure post-call analytics?
Within AmazonTranscribeCallAnalyticsProcessor, set postCallAnalyticsSettings with a separate IAM role ARN (dataAccessRoleArn), output location, and optional encryption settings. This role requires Transcribe service permissions.

Using a different cloud?

Explore analytics guides for other cloud providers: