Create AWS CloudWatch Evidently Projects

The aws:evidently/project:Project resource, part of the Pulumi AWS provider, defines a CloudWatch Evidently project that serves as a container for feature flags and experiments. This resource is deprecated; AWS recommends using AppConfig feature flags instead. This guide focuses on three capabilities: project creation with metadata, evaluation event delivery to CloudWatch Logs, and evaluation event archival to S3.

Evidently projects may reference CloudWatch Log Groups or S3 buckets for storing evaluation events. The examples are intentionally small. Combine them with your own logging infrastructure and feature flag resources.

Create a project with name and tags

Most Evidently deployments start with a minimal project definition that establishes the container for features and experiments.

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

const example = new aws.evidently.Project("example", {
    name: "Example",
    description: "Example Description",
    tags: {
        Key1: "example Project",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.evidently.Project("example",
    name="Example",
    description="Example Description",
    tags={
        "Key1": "example Project",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := evidently.NewProject(ctx, "example", &evidently.ProjectArgs{
			Name:        pulumi.String("Example"),
			Description: pulumi.String("Example Description"),
			Tags: pulumi.StringMap{
				"Key1": pulumi.String("example Project"),
			},
		})
		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.Evidently.Project("example", new()
    {
        Name = "Example",
        Description = "Example Description",
        Tags = 
        {
            { "Key1", "example Project" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.evidently.Project;
import com.pulumi.aws.evidently.ProjectArgs;
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 Project("example", ProjectArgs.builder()
            .name("Example")
            .description("Example Description")
            .tags(Map.of("Key1", "example Project"))
            .build());

    }
}
resources:
  example:
    type: aws:evidently:Project
    properties:
      name: Example
      description: Example Description
      tags:
        Key1: example Project

The name property sets the project identifier. The description and tags properties add metadata for organization and cost tracking. Without dataDelivery configuration, Evidently deletes evaluation events after producing metrics and experiment results.

Send evaluation events to CloudWatch Logs

Teams analyzing feature flag behavior alongside application logs can route evaluation events to CloudWatch Log Groups.

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

const example = new aws.evidently.Project("example", {
    name: "Example",
    description: "Example Description",
    dataDelivery: {
        cloudwatchLogs: {
            logGroup: "example-log-group-name",
        },
    },
    tags: {
        Key1: "example Project",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.evidently.Project("example",
    name="Example",
    description="Example Description",
    data_delivery={
        "cloudwatch_logs": {
            "log_group": "example-log-group-name",
        },
    },
    tags={
        "Key1": "example Project",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := evidently.NewProject(ctx, "example", &evidently.ProjectArgs{
			Name:        pulumi.String("Example"),
			Description: pulumi.String("Example Description"),
			DataDelivery: &evidently.ProjectDataDeliveryArgs{
				CloudwatchLogs: &evidently.ProjectDataDeliveryCloudwatchLogsArgs{
					LogGroup: pulumi.String("example-log-group-name"),
				},
			},
			Tags: pulumi.StringMap{
				"Key1": pulumi.String("example Project"),
			},
		})
		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.Evidently.Project("example", new()
    {
        Name = "Example",
        Description = "Example Description",
        DataDelivery = new Aws.Evidently.Inputs.ProjectDataDeliveryArgs
        {
            CloudwatchLogs = new Aws.Evidently.Inputs.ProjectDataDeliveryCloudwatchLogsArgs
            {
                LogGroup = "example-log-group-name",
            },
        },
        Tags = 
        {
            { "Key1", "example Project" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.evidently.Project;
import com.pulumi.aws.evidently.ProjectArgs;
import com.pulumi.aws.evidently.inputs.ProjectDataDeliveryArgs;
import com.pulumi.aws.evidently.inputs.ProjectDataDeliveryCloudwatchLogsArgs;
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 Project("example", ProjectArgs.builder()
            .name("Example")
            .description("Example Description")
            .dataDelivery(ProjectDataDeliveryArgs.builder()
                .cloudwatchLogs(ProjectDataDeliveryCloudwatchLogsArgs.builder()
                    .logGroup("example-log-group-name")
                    .build())
                .build())
            .tags(Map.of("Key1", "example Project"))
            .build());

    }
}
resources:
  example:
    type: aws:evidently:Project
    properties:
      name: Example
      description: Example Description
      dataDelivery:
        cloudwatchLogs:
          logGroup: example-log-group-name
      tags:
        Key1: example Project

The dataDelivery block configures where Evidently sends evaluation events. The cloudwatchLogs property specifies a log group name where events are written, enabling centralized monitoring with your application logs.

Archive evaluation events to S3

For long-term storage and compliance, evaluation events can be archived to S3 instead of CloudWatch Logs.

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

const example = new aws.evidently.Project("example", {
    name: "Example",
    description: "Example Description",
    dataDelivery: {
        s3Destination: {
            bucket: "example-bucket-name",
            prefix: "example",
        },
    },
    tags: {
        Key1: "example Project",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.evidently.Project("example",
    name="Example",
    description="Example Description",
    data_delivery={
        "s3_destination": {
            "bucket": "example-bucket-name",
            "prefix": "example",
        },
    },
    tags={
        "Key1": "example Project",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := evidently.NewProject(ctx, "example", &evidently.ProjectArgs{
			Name:        pulumi.String("Example"),
			Description: pulumi.String("Example Description"),
			DataDelivery: &evidently.ProjectDataDeliveryArgs{
				S3Destination: &evidently.ProjectDataDeliveryS3DestinationArgs{
					Bucket: pulumi.String("example-bucket-name"),
					Prefix: pulumi.String("example"),
				},
			},
			Tags: pulumi.StringMap{
				"Key1": pulumi.String("example Project"),
			},
		})
		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.Evidently.Project("example", new()
    {
        Name = "Example",
        Description = "Example Description",
        DataDelivery = new Aws.Evidently.Inputs.ProjectDataDeliveryArgs
        {
            S3Destination = new Aws.Evidently.Inputs.ProjectDataDeliveryS3DestinationArgs
            {
                Bucket = "example-bucket-name",
                Prefix = "example",
            },
        },
        Tags = 
        {
            { "Key1", "example Project" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.evidently.Project;
import com.pulumi.aws.evidently.ProjectArgs;
import com.pulumi.aws.evidently.inputs.ProjectDataDeliveryArgs;
import com.pulumi.aws.evidently.inputs.ProjectDataDeliveryS3DestinationArgs;
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 Project("example", ProjectArgs.builder()
            .name("Example")
            .description("Example Description")
            .dataDelivery(ProjectDataDeliveryArgs.builder()
                .s3Destination(ProjectDataDeliveryS3DestinationArgs.builder()
                    .bucket("example-bucket-name")
                    .prefix("example")
                    .build())
                .build())
            .tags(Map.of("Key1", "example Project"))
            .build());

    }
}
resources:
  example:
    type: aws:evidently:Project
    properties:
      name: Example
      description: Example Description
      dataDelivery:
        s3Destination:
          bucket: example-bucket-name
          prefix: example
      tags:
        Key1: example Project

The s3Destination property routes evaluation events to an S3 bucket with an optional prefix. This approach reduces CloudWatch Logs retention costs while preserving historical data for analysis.

Beyond these examples

These snippets focus on specific project-level features: project creation and tagging, and evaluation event delivery to CloudWatch Logs and S3. They’re intentionally minimal rather than full feature flag deployments.

The examples may reference pre-existing infrastructure such as CloudWatch Log Groups for log delivery, and S3 buckets for S3 delivery. They focus on configuring the project rather than provisioning everything around it.

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

  • Feature flag and experiment configuration (separate resources)
  • IAM permissions for data delivery destinations
  • Event retention and lifecycle policies

These omissions are intentional: the goal is to illustrate how each project feature is wired, not provide drop-in feature flag modules. See the Evidently Project resource reference for all available configuration options.

Let's create AWS CloudWatch Evidently Projects

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Deprecation & Migration
Should I use CloudWatch Evidently Projects for new deployments?
No, this resource is deprecated. Use AWS AppConfig feature flags instead for new projects.
Configuration & Setup
What's required to create an Evidently project?
Only name is required. The region defaults to your provider configuration, and other properties like description and dataDelivery are optional.
Where can I store evaluation events for long-term analysis?

You have three options:

  1. CloudWatch Logs - Configure dataDelivery.cloudwatchLogs.logGroup
  2. S3 bucket - Configure dataDelivery.s3Destination with bucket and optional prefix
  3. No storage - If you don’t configure dataDelivery, Evidently deletes events after producing metrics
Limitations & Immutability
Can I rename my Evidently project after creation?
No, the name property is immutable. Changing it requires replacing the entire resource.

Using a different cloud?

Explore monitoring guides for other cloud providers: