The aws:ivschat/loggingConfiguration:LoggingConfiguration resource, part of the Pulumi AWS provider, defines where IVS Chat logs are delivered: CloudWatch Logs, Kinesis Firehose, or S3. This guide focuses on three capabilities: CloudWatch Logs integration, Firehose streaming to S3, and direct S3 delivery.
Logging configurations reference existing log groups, Firehose streams, or S3 buckets. The examples are intentionally small. Combine them with your own log destinations and IAM policies.
Send chat logs to CloudWatch Logs
Teams monitoring live chat activity often route logs to CloudWatch for centralized observability alongside other application logs.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.cloudwatch.LogGroup("example", {});
const exampleLoggingConfiguration = new aws.ivschat.LoggingConfiguration("example", {destinationConfiguration: {
cloudwatchLogs: {
logGroupName: example.name,
},
}});
import pulumi
import pulumi_aws as aws
example = aws.cloudwatch.LogGroup("example")
example_logging_configuration = aws.ivschat.LoggingConfiguration("example", destination_configuration={
"cloudwatch_logs": {
"log_group_name": example.name,
},
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cloudwatch"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ivschat"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
example, err := cloudwatch.NewLogGroup(ctx, "example", nil)
if err != nil {
return err
}
_, err = ivschat.NewLoggingConfiguration(ctx, "example", &ivschat.LoggingConfigurationArgs{
DestinationConfiguration: &ivschat.LoggingConfigurationDestinationConfigurationArgs{
CloudwatchLogs: &ivschat.LoggingConfigurationDestinationConfigurationCloudwatchLogsArgs{
LogGroupName: example.Name,
},
},
})
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.CloudWatch.LogGroup("example");
var exampleLoggingConfiguration = new Aws.IvsChat.LoggingConfiguration("example", new()
{
DestinationConfiguration = new Aws.IvsChat.Inputs.LoggingConfigurationDestinationConfigurationArgs
{
CloudwatchLogs = new Aws.IvsChat.Inputs.LoggingConfigurationDestinationConfigurationCloudwatchLogsArgs
{
LogGroupName = example.Name,
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.cloudwatch.LogGroup;
import com.pulumi.aws.ivschat.LoggingConfiguration;
import com.pulumi.aws.ivschat.LoggingConfigurationArgs;
import com.pulumi.aws.ivschat.inputs.LoggingConfigurationDestinationConfigurationArgs;
import com.pulumi.aws.ivschat.inputs.LoggingConfigurationDestinationConfigurationCloudwatchLogsArgs;
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 LogGroup("example");
var exampleLoggingConfiguration = new LoggingConfiguration("exampleLoggingConfiguration", LoggingConfigurationArgs.builder()
.destinationConfiguration(LoggingConfigurationDestinationConfigurationArgs.builder()
.cloudwatchLogs(LoggingConfigurationDestinationConfigurationCloudwatchLogsArgs.builder()
.logGroupName(example.name())
.build())
.build())
.build());
}
}
resources:
example:
type: aws:cloudwatch:LogGroup
exampleLoggingConfiguration:
type: aws:ivschat:LoggingConfiguration
name: example
properties:
destinationConfiguration:
cloudwatchLogs:
logGroupName: ${example.name}
The destinationConfiguration property specifies where logs are sent. The cloudwatchLogs block routes chat activity to a CloudWatch log group, enabling queries, metric filters, and alarms. You must create the log group separately.
Stream chat logs through Firehose to S3
Applications that need to archive chat activity or feed logs into analytics pipelines route messages through Kinesis Firehose for transformation and delivery to S3.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const exampleBucket = new aws.s3.Bucket("example", {bucketPrefix: "tf-ivschat-logging-bucket"});
const assumeRole = aws.iam.getPolicyDocument({
statements: [{
effect: "Allow",
principals: [{
type: "Service",
identifiers: ["firehose.amazonaws.com"],
}],
actions: ["sts:AssumeRole"],
}],
});
const exampleRole = new aws.iam.Role("example", {
name: "firehose_example_role",
assumeRolePolicy: assumeRole.then(assumeRole => assumeRole.json),
});
const example = new aws.kinesis.FirehoseDeliveryStream("example", {
name: "pulumi-kinesis-firehose-extended-s3-example-stream",
destination: "extended_s3",
extendedS3Configuration: {
roleArn: exampleRole.arn,
bucketArn: exampleBucket.arn,
},
tags: {
LogDeliveryEnabled: "true",
},
});
const exampleBucketAcl = new aws.s3.BucketAcl("example", {
bucket: exampleBucket.id,
acl: "private",
});
const exampleLoggingConfiguration = new aws.ivschat.LoggingConfiguration("example", {destinationConfiguration: {
firehose: {
deliveryStreamName: example.name,
},
}});
import pulumi
import pulumi_aws as aws
example_bucket = aws.s3.Bucket("example", bucket_prefix="tf-ivschat-logging-bucket")
assume_role = aws.iam.get_policy_document(statements=[{
"effect": "Allow",
"principals": [{
"type": "Service",
"identifiers": ["firehose.amazonaws.com"],
}],
"actions": ["sts:AssumeRole"],
}])
example_role = aws.iam.Role("example",
name="firehose_example_role",
assume_role_policy=assume_role.json)
example = aws.kinesis.FirehoseDeliveryStream("example",
name="pulumi-kinesis-firehose-extended-s3-example-stream",
destination="extended_s3",
extended_s3_configuration={
"role_arn": example_role.arn,
"bucket_arn": example_bucket.arn,
},
tags={
"LogDeliveryEnabled": "true",
})
example_bucket_acl = aws.s3.BucketAcl("example",
bucket=example_bucket.id,
acl="private")
example_logging_configuration = aws.ivschat.LoggingConfiguration("example", destination_configuration={
"firehose": {
"delivery_stream_name": example.name,
},
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ivschat"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/kinesis"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
exampleBucket, err := s3.NewBucket(ctx, "example", &s3.BucketArgs{
BucketPrefix: pulumi.String("tf-ivschat-logging-bucket"),
})
if err != nil {
return err
}
assumeRole, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
Statements: []iam.GetPolicyDocumentStatement{
{
Effect: pulumi.StringRef("Allow"),
Principals: []iam.GetPolicyDocumentStatementPrincipal{
{
Type: "Service",
Identifiers: []string{
"firehose.amazonaws.com",
},
},
},
Actions: []string{
"sts:AssumeRole",
},
},
},
}, nil)
if err != nil {
return err
}
exampleRole, err := iam.NewRole(ctx, "example", &iam.RoleArgs{
Name: pulumi.String("firehose_example_role"),
AssumeRolePolicy: pulumi.String(assumeRole.Json),
})
if err != nil {
return err
}
example, err := kinesis.NewFirehoseDeliveryStream(ctx, "example", &kinesis.FirehoseDeliveryStreamArgs{
Name: pulumi.String("pulumi-kinesis-firehose-extended-s3-example-stream"),
Destination: pulumi.String("extended_s3"),
ExtendedS3Configuration: &kinesis.FirehoseDeliveryStreamExtendedS3ConfigurationArgs{
RoleArn: exampleRole.Arn,
BucketArn: exampleBucket.Arn,
},
Tags: pulumi.StringMap{
"LogDeliveryEnabled": pulumi.String("true"),
},
})
if err != nil {
return err
}
_, err = s3.NewBucketAcl(ctx, "example", &s3.BucketAclArgs{
Bucket: exampleBucket.ID(),
Acl: pulumi.String("private"),
})
if err != nil {
return err
}
_, err = ivschat.NewLoggingConfiguration(ctx, "example", &ivschat.LoggingConfigurationArgs{
DestinationConfiguration: &ivschat.LoggingConfigurationDestinationConfigurationArgs{
Firehose: &ivschat.LoggingConfigurationDestinationConfigurationFirehoseArgs{
DeliveryStreamName: example.Name,
},
},
})
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 exampleBucket = new Aws.S3.Bucket("example", new()
{
BucketPrefix = "tf-ivschat-logging-bucket",
});
var assumeRole = 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[]
{
"firehose.amazonaws.com",
},
},
},
Actions = new[]
{
"sts:AssumeRole",
},
},
},
});
var exampleRole = new Aws.Iam.Role("example", new()
{
Name = "firehose_example_role",
AssumeRolePolicy = assumeRole.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
});
var example = new Aws.Kinesis.FirehoseDeliveryStream("example", new()
{
Name = "pulumi-kinesis-firehose-extended-s3-example-stream",
Destination = "extended_s3",
ExtendedS3Configuration = new Aws.Kinesis.Inputs.FirehoseDeliveryStreamExtendedS3ConfigurationArgs
{
RoleArn = exampleRole.Arn,
BucketArn = exampleBucket.Arn,
},
Tags =
{
{ "LogDeliveryEnabled", "true" },
},
});
var exampleBucketAcl = new Aws.S3.BucketAcl("example", new()
{
Bucket = exampleBucket.Id,
Acl = "private",
});
var exampleLoggingConfiguration = new Aws.IvsChat.LoggingConfiguration("example", new()
{
DestinationConfiguration = new Aws.IvsChat.Inputs.LoggingConfigurationDestinationConfigurationArgs
{
Firehose = new Aws.IvsChat.Inputs.LoggingConfigurationDestinationConfigurationFirehoseArgs
{
DeliveryStreamName = example.Name,
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.s3.Bucket;
import com.pulumi.aws.s3.BucketArgs;
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.kinesis.FirehoseDeliveryStream;
import com.pulumi.aws.kinesis.FirehoseDeliveryStreamArgs;
import com.pulumi.aws.kinesis.inputs.FirehoseDeliveryStreamExtendedS3ConfigurationArgs;
import com.pulumi.aws.s3.BucketAcl;
import com.pulumi.aws.s3.BucketAclArgs;
import com.pulumi.aws.ivschat.LoggingConfiguration;
import com.pulumi.aws.ivschat.LoggingConfigurationArgs;
import com.pulumi.aws.ivschat.inputs.LoggingConfigurationDestinationConfigurationArgs;
import com.pulumi.aws.ivschat.inputs.LoggingConfigurationDestinationConfigurationFirehoseArgs;
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 exampleBucket = new Bucket("exampleBucket", BucketArgs.builder()
.bucketPrefix("tf-ivschat-logging-bucket")
.build());
final var assumeRole = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
.statements(GetPolicyDocumentStatementArgs.builder()
.effect("Allow")
.principals(GetPolicyDocumentStatementPrincipalArgs.builder()
.type("Service")
.identifiers("firehose.amazonaws.com")
.build())
.actions("sts:AssumeRole")
.build())
.build());
var exampleRole = new Role("exampleRole", RoleArgs.builder()
.name("firehose_example_role")
.assumeRolePolicy(assumeRole.json())
.build());
var example = new FirehoseDeliveryStream("example", FirehoseDeliveryStreamArgs.builder()
.name("pulumi-kinesis-firehose-extended-s3-example-stream")
.destination("extended_s3")
.extendedS3Configuration(FirehoseDeliveryStreamExtendedS3ConfigurationArgs.builder()
.roleArn(exampleRole.arn())
.bucketArn(exampleBucket.arn())
.build())
.tags(Map.of("LogDeliveryEnabled", "true"))
.build());
var exampleBucketAcl = new BucketAcl("exampleBucketAcl", BucketAclArgs.builder()
.bucket(exampleBucket.id())
.acl("private")
.build());
var exampleLoggingConfiguration = new LoggingConfiguration("exampleLoggingConfiguration", LoggingConfigurationArgs.builder()
.destinationConfiguration(LoggingConfigurationDestinationConfigurationArgs.builder()
.firehose(LoggingConfigurationDestinationConfigurationFirehoseArgs.builder()
.deliveryStreamName(example.name())
.build())
.build())
.build());
}
}
resources:
example:
type: aws:kinesis:FirehoseDeliveryStream
properties:
name: pulumi-kinesis-firehose-extended-s3-example-stream
destination: extended_s3
extendedS3Configuration:
roleArn: ${exampleRole.arn}
bucketArn: ${exampleBucket.arn}
tags:
LogDeliveryEnabled: 'true'
exampleBucket:
type: aws:s3:Bucket
name: example
properties:
bucketPrefix: tf-ivschat-logging-bucket
exampleBucketAcl:
type: aws:s3:BucketAcl
name: example
properties:
bucket: ${exampleBucket.id}
acl: private
exampleRole:
type: aws:iam:Role
name: example
properties:
name: firehose_example_role
assumeRolePolicy: ${assumeRole.json}
exampleLoggingConfiguration:
type: aws:ivschat:LoggingConfiguration
name: example
properties:
destinationConfiguration:
firehose:
deliveryStreamName: ${example.name}
variables:
assumeRole:
fn::invoke:
function: aws:iam:getPolicyDocument
arguments:
statements:
- effect: Allow
principals:
- type: Service
identifiers:
- firehose.amazonaws.com
actions:
- sts:AssumeRole
The firehose block sends logs to a Firehose delivery stream, which handles buffering, transformation, and S3 delivery. The deliveryStreamName references your stream. Firehose requires an IAM role with S3 write permissions and a destination bucket.
Write chat logs directly to S3
For simple archival without transformation, IVS Chat can write logs directly to S3, bypassing intermediate streaming services.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.s3.Bucket("example", {
bucketName: "tf-ivschat-logging",
forceDestroy: true,
});
const exampleLoggingConfiguration = new aws.ivschat.LoggingConfiguration("example", {destinationConfiguration: {
s3: {
bucketName: example.id,
},
}});
import pulumi
import pulumi_aws as aws
example = aws.s3.Bucket("example",
bucket_name="tf-ivschat-logging",
force_destroy=True)
example_logging_configuration = aws.ivschat.LoggingConfiguration("example", destination_configuration={
"s3": {
"bucket_name": example.id,
},
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/ivschat"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/s3"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
example, err := s3.NewBucket(ctx, "example", &s3.BucketArgs{
BucketName: "tf-ivschat-logging",
ForceDestroy: pulumi.Bool(true),
})
if err != nil {
return err
}
_, err = ivschat.NewLoggingConfiguration(ctx, "example", &ivschat.LoggingConfigurationArgs{
DestinationConfiguration: &ivschat.LoggingConfigurationDestinationConfigurationArgs{
S3: &ivschat.LoggingConfigurationDestinationConfigurationS3Args{
BucketName: example.ID(),
},
},
})
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.S3.Bucket("example", new()
{
BucketName = "tf-ivschat-logging",
ForceDestroy = true,
});
var exampleLoggingConfiguration = new Aws.IvsChat.LoggingConfiguration("example", new()
{
DestinationConfiguration = new Aws.IvsChat.Inputs.LoggingConfigurationDestinationConfigurationArgs
{
S3 = new Aws.IvsChat.Inputs.LoggingConfigurationDestinationConfigurationS3Args
{
BucketName = example.Id,
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.s3.Bucket;
import com.pulumi.aws.s3.BucketArgs;
import com.pulumi.aws.ivschat.LoggingConfiguration;
import com.pulumi.aws.ivschat.LoggingConfigurationArgs;
import com.pulumi.aws.ivschat.inputs.LoggingConfigurationDestinationConfigurationArgs;
import com.pulumi.aws.ivschat.inputs.LoggingConfigurationDestinationConfigurationS3Args;
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 Bucket("example", BucketArgs.builder()
.bucketName("tf-ivschat-logging")
.forceDestroy(true)
.build());
var exampleLoggingConfiguration = new LoggingConfiguration("exampleLoggingConfiguration", LoggingConfigurationArgs.builder()
.destinationConfiguration(LoggingConfigurationDestinationConfigurationArgs.builder()
.s3(LoggingConfigurationDestinationConfigurationS3Args.builder()
.bucketName(example.id())
.build())
.build())
.build());
}
}
resources:
example:
type: aws:s3:Bucket
properties:
bucketName: tf-ivschat-logging
forceDestroy: true
exampleLoggingConfiguration:
type: aws:ivschat:LoggingConfiguration
name: example
properties:
destinationConfiguration:
s3:
bucketName: ${example.id}
The s3 block delivers logs straight to an S3 bucket. The bucketName property references your bucket. This approach skips Firehose’s buffering and transformation, providing simpler archival for compliance or long-term storage.
Beyond these examples
These snippets focus on specific logging configuration features: CloudWatch, Firehose, and S3 destinations. They’re intentionally minimal rather than full logging pipelines.
The examples reference pre-existing infrastructure such as CloudWatch log groups, Firehose delivery streams, S3 buckets, and IAM roles for Firehose (when using Firehose destination). They focus on configuring the logging destination rather than provisioning the underlying infrastructure.
To keep things focused, common logging patterns are omitted, including:
- Logging configuration naming (name property)
- Resource tagging (tags property)
- Cross-region configuration (region property)
These omissions are intentional: the goal is to illustrate how each destination type is wired, not provide drop-in logging modules. See the IVS Chat LoggingConfiguration resource reference for all available configuration options.
Let's configure AWS IVS Chat Logging
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Destination Configuration
cloudwatchLogs), Kinesis Firehose (firehose), or S3 (s3). Each destination type is shown in the provided examples.destinationConfiguration must contain exactly one destination type. Choose either cloudwatchLogs, firehose, or s3.s3 logging writes to a bucket using bucketName. The firehose destination routes logs through a Kinesis Firehose delivery stream (with extended_s3 configuration), requiring additional IAM role setup.Setup & IAM Requirements
firehose.amazonaws.com to assume the role via sts:AssumeRole. The role ARN is passed to extendedS3Configuration.roleArn.Using a different cloud?
Explore monitoring guides for other cloud providers: