Create AWS Managed Service for Prometheus Workspaces

The aws:amp/workspace:Workspace resource, part of the Pulumi AWS provider, provisions an Amazon Managed Service for Prometheus workspace: the container for storing and querying Prometheus metrics. This guide focuses on three capabilities: workspace creation with aliases and tags, CloudWatch logging integration, and customer-managed encryption.

Workspaces are the foundation for AMP deployments. They may reference CloudWatch log groups for operational logging and KMS keys for encryption. The examples are intentionally small. Combine them with your own Prometheus agents, remote write configuration, and IAM policies.

Create a workspace with an alias and tags

Most deployments start by creating a workspace with a human-readable alias and organizational tags.

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

const example = new aws.amp.Workspace("example", {
    alias: "example",
    tags: {
        Environment: "production",
    },
});
import pulumi
import pulumi_aws as aws

example = aws.amp.Workspace("example",
    alias="example",
    tags={
        "Environment": "production",
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := amp.NewWorkspace(ctx, "example", &amp.WorkspaceArgs{
			Alias: pulumi.String("example"),
			Tags: pulumi.StringMap{
				"Environment": pulumi.String("production"),
			},
		})
		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.Amp.Workspace("example", new()
    {
        Alias = "example",
        Tags = 
        {
            { "Environment", "production" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.amp.Workspace;
import com.pulumi.aws.amp.WorkspaceArgs;
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 Workspace("example", WorkspaceArgs.builder()
            .alias("example")
            .tags(Map.of("Environment", "production"))
            .build());

    }
}
resources:
  example:
    type: aws:amp:Workspace
    properties:
      alias: example
      tags:
        Environment: production

The alias property provides a friendly name for the workspace, making it easier to identify in the console and CLI. The tags property adds metadata for cost tracking and organization. Without additional configuration, the workspace uses AWS-owned encryption keys and doesn’t send operational logs to CloudWatch.

Send workspace logs to CloudWatch

Teams that need visibility into workspace operations configure CloudWatch logging to capture query execution and ingestion errors.

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

const example = new aws.cloudwatch.LogGroup("example", {name: "example"});
const exampleWorkspace = new aws.amp.Workspace("example", {loggingConfiguration: {
    logGroupArn: pulumi.interpolate`${example.arn}:*`,
}});
import pulumi
import pulumi_aws as aws

example = aws.cloudwatch.LogGroup("example", name="example")
example_workspace = aws.amp.Workspace("example", logging_configuration={
    "log_group_arn": example.arn.apply(lambda arn: f"{arn}:*"),
})
package main

import (
	"fmt"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/amp"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cloudwatch"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		example, err := cloudwatch.NewLogGroup(ctx, "example", &cloudwatch.LogGroupArgs{
			Name: pulumi.String("example"),
		})
		if err != nil {
			return err
		}
		_, err = amp.NewWorkspace(ctx, "example", &amp.WorkspaceArgs{
			LoggingConfiguration: &amp.WorkspaceLoggingConfigurationArgs{
				LogGroupArn: example.Arn.ApplyT(func(arn string) (string, error) {
					return fmt.Sprintf("%v:*", arn), nil
				}).(pulumi.StringOutput),
			},
		})
		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", new()
    {
        Name = "example",
    });

    var exampleWorkspace = new Aws.Amp.Workspace("example", new()
    {
        LoggingConfiguration = new Aws.Amp.Inputs.WorkspaceLoggingConfigurationArgs
        {
            LogGroupArn = example.Arn.Apply(arn => $"{arn}:*"),
        },
    });

});
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.cloudwatch.LogGroupArgs;
import com.pulumi.aws.amp.Workspace;
import com.pulumi.aws.amp.WorkspaceArgs;
import com.pulumi.aws.amp.inputs.WorkspaceLoggingConfigurationArgs;
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", LogGroupArgs.builder()
            .name("example")
            .build());

        var exampleWorkspace = new Workspace("exampleWorkspace", WorkspaceArgs.builder()
            .loggingConfiguration(WorkspaceLoggingConfigurationArgs.builder()
                .logGroupArn(example.arn().applyValue(_arn -> String.format("%s:*", _arn)))
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:cloudwatch:LogGroup
    properties:
      name: example
  exampleWorkspace:
    type: aws:amp:Workspace
    name: example
    properties:
      loggingConfiguration:
        logGroupArn: ${example.arn}:*

The loggingConfiguration property directs workspace operational logs to a CloudWatch log group. The logGroupArn must include the :* suffix to allow the workspace to create log streams. This captures query activity, ingestion errors, and API calls for troubleshooting.

Encrypt workspace data with customer-managed keys

Organizations with compliance requirements use customer-managed KMS keys to control encryption of metrics data.

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

const exampleKey = new aws.kms.Key("example", {
    description: "example",
    deletionWindowInDays: 7,
});
const example = new aws.amp.Workspace("example", {
    alias: "example",
    kmsKeyArn: exampleKey.arn,
});
import pulumi
import pulumi_aws as aws

example_key = aws.kms.Key("example",
    description="example",
    deletion_window_in_days=7)
example = aws.amp.Workspace("example",
    alias="example",
    kms_key_arn=example_key.arn)
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		exampleKey, err := kms.NewKey(ctx, "example", &kms.KeyArgs{
			Description:          pulumi.String("example"),
			DeletionWindowInDays: pulumi.Int(7),
		})
		if err != nil {
			return err
		}
		_, err = amp.NewWorkspace(ctx, "example", &amp.WorkspaceArgs{
			Alias:     pulumi.String("example"),
			KmsKeyArn: exampleKey.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 exampleKey = new Aws.Kms.Key("example", new()
    {
        Description = "example",
        DeletionWindowInDays = 7,
    });

    var example = new Aws.Amp.Workspace("example", new()
    {
        Alias = "example",
        KmsKeyArn = exampleKey.Arn,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.kms.Key;
import com.pulumi.aws.kms.KeyArgs;
import com.pulumi.aws.amp.Workspace;
import com.pulumi.aws.amp.WorkspaceArgs;
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 exampleKey = new Key("exampleKey", KeyArgs.builder()
            .description("example")
            .deletionWindowInDays(7)
            .build());

        var example = new Workspace("example", WorkspaceArgs.builder()
            .alias("example")
            .kmsKeyArn(exampleKey.arn())
            .build());

    }
}
resources:
  example:
    type: aws:amp:Workspace
    properties:
      alias: example
      kmsKeyArn: ${exampleKey.arn}
  exampleKey:
    type: aws:kms:Key
    name: example
    properties:
      description: example
      deletionWindowInDays: 7

The kmsKeyArn property specifies a customer-managed KMS key for encrypting metrics data at rest. This is immutable after workspace creation. The KMS key policy must grant the AMP service principal permissions to decrypt and generate data keys. Without this property, AWS-owned encryption keys are used.

Beyond these examples

These snippets focus on specific workspace-level features: workspace naming and tagging, CloudWatch logging integration, and customer-managed encryption keys. They’re intentionally minimal rather than full monitoring deployments.

The examples may reference pre-existing infrastructure such as CloudWatch log groups for logging configuration, and KMS keys with appropriate permissions for encryption. They focus on configuring the workspace rather than provisioning everything around it.

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

  • Prometheus remote write configuration (done via separate scraper/agent setup)
  • Query and alerting rule configuration (managed outside workspace resource)
  • IAM policies for workspace access (separate from workspace creation)
  • Network configuration and VPC endpoints (if using private connectivity)

These omissions are intentional: the goal is to illustrate how each workspace feature is wired, not provide drop-in monitoring modules. See the AMP Workspace resource reference for all available configuration options.

Let's create AWS Managed Service for Prometheus Workspaces

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Encryption & Security
What encryption options are available and can I change them later?
AMP workspaces use AWS-owned encryption keys by default. You can specify a customer-managed KMS key using kmsKeyArn, but this property is immutable—changing it requires recreating the workspace.
How do I use a customer-managed KMS key for encryption?
Provide the kmsKeyArn property with your KMS key ARN during workspace creation. If omitted, AWS-owned encryption is used automatically.
Logging & Monitoring
How do I configure CloudWatch logging for my workspace?
Set loggingConfiguration with logGroupArn pointing to your CloudWatch log group. The ARN must include a :* suffix, like ${logGroup.arn}:*.
How do I access the Prometheus endpoint after creating a workspace?
The prometheusEndpoint output property provides the endpoint URL for querying and ingesting metrics.
Configuration & Setup
What's the minimal configuration needed to create an AMP workspace?
No properties are strictly required beyond region, which defaults to your provider configuration. You can create a workspace with just an alias or tags.
What's the difference between alias and the workspace identifier?
The alias is an optional friendly name you assign. The workspace identifier (like ws-C6DCB907-F2D7-4D96-957B-66691F865D8B) is auto-generated by AWS and used for import operations.
Can I use provider default tags with AMP workspaces?
Yes, tags defined in the provider’s defaultTags configuration are automatically applied and merged with workspace-specific tags.

Using a different cloud?

Explore monitoring guides for other cloud providers: