Configure AWS CloudWatch Observability Centralization Rules

The aws:observabilityadmin/centralizationRuleForOrganization:CentralizationRuleForOrganization resource, part of the Pulumi AWS provider, defines organization-wide rules that centralize CloudWatch logs from multiple accounts and regions to a single destination. This guide focuses on three capabilities: cross-region log centralization, log group filtering with pattern matching, and encryption and backup configuration.

Centralization rules require an AWS Organizations setup with delegated administrator permissions and appropriate IAM roles in both source and destination accounts. The examples are intentionally small. Combine them with your own IAM policies, log group configurations, and retention settings.

Centralize logs from one region to another

Organizations consolidate CloudWatch logs from multiple accounts and regions into a single destination for unified monitoring and compliance.

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

const current = aws.getCallerIdentity({});
const currentGetOrganization = aws.organizations.getOrganization({});
const example = new aws.observabilityadmin.CentralizationRuleForOrganization("example", {
    ruleName: "example-centralization-rule",
    rule: {
        destination: {
            region: "eu-west-1",
            account: current.then(current => current.accountId),
        },
        source: {
            regions: ["ap-southeast-1"],
            scope: currentGetOrganization.then(currentGetOrganization => `OrganizationId = '${currentGetOrganization.id}'`),
            sourceLogsConfiguration: {
                encryptedLogGroupStrategy: "SKIP",
                logGroupSelectionCriteria: "*",
            },
        },
    },
    tags: {
        Name: "example-centralization-rule",
        Environment: "production",
    },
});
import pulumi
import pulumi_aws as aws

current = aws.get_caller_identity()
current_get_organization = aws.organizations.get_organization()
example = aws.observabilityadmin.CentralizationRuleForOrganization("example",
    rule_name="example-centralization-rule",
    rule={
        "destination": {
            "region": "eu-west-1",
            "account": current.account_id,
        },
        "source": {
            "regions": ["ap-southeast-1"],
            "scope": f"OrganizationId = '{current_get_organization.id}'",
            "source_logs_configuration": {
                "encrypted_log_group_strategy": "SKIP",
                "log_group_selection_criteria": "*",
            },
        },
    },
    tags={
        "Name": "example-centralization-rule",
        "Environment": "production",
    })
package main

import (
	"fmt"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/observabilityadmin"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/organizations"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		current, err := aws.GetCallerIdentity(ctx, &aws.GetCallerIdentityArgs{}, nil)
		if err != nil {
			return err
		}
		currentGetOrganization, err := organizations.LookupOrganization(ctx, map[string]interface{}{}, nil)
		if err != nil {
			return err
		}
		_, err = observabilityadmin.NewCentralizationRuleForOrganization(ctx, "example", &observabilityadmin.CentralizationRuleForOrganizationArgs{
			RuleName: pulumi.String("example-centralization-rule"),
			Rule: &observabilityadmin.CentralizationRuleForOrganizationRuleArgs{
				Destination: &observabilityadmin.CentralizationRuleForOrganizationRuleDestinationArgs{
					Region:  pulumi.String("eu-west-1"),
					Account: pulumi.String(current.AccountId),
				},
				Source: &observabilityadmin.CentralizationRuleForOrganizationRuleSourceArgs{
					Regions: pulumi.StringArray{
						pulumi.String("ap-southeast-1"),
					},
					Scope: pulumi.Sprintf("OrganizationId = '%v'", currentGetOrganization.Id),
					SourceLogsConfiguration: &observabilityadmin.CentralizationRuleForOrganizationRuleSourceSourceLogsConfigurationArgs{
						EncryptedLogGroupStrategy: pulumi.String("SKIP"),
						LogGroupSelectionCriteria: pulumi.String("*"),
					},
				},
			},
			Tags: pulumi.StringMap{
				"Name":        pulumi.String("example-centralization-rule"),
				"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 current = Aws.GetCallerIdentity.Invoke();

    var currentGetOrganization = Aws.Organizations.GetOrganization.Invoke();

    var example = new Aws.Observabilityadmin.CentralizationRuleForOrganization("example", new()
    {
        RuleName = "example-centralization-rule",
        Rule = new Aws.Observabilityadmin.Inputs.CentralizationRuleForOrganizationRuleArgs
        {
            Destination = new Aws.Observabilityadmin.Inputs.CentralizationRuleForOrganizationRuleDestinationArgs
            {
                Region = "eu-west-1",
                Account = current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId),
            },
            Source = new Aws.Observabilityadmin.Inputs.CentralizationRuleForOrganizationRuleSourceArgs
            {
                Regions = new[]
                {
                    "ap-southeast-1",
                },
                Scope = $"OrganizationId = '{currentGetOrganization.Apply(getOrganizationResult => getOrganizationResult.Id)}'",
                SourceLogsConfiguration = new Aws.Observabilityadmin.Inputs.CentralizationRuleForOrganizationRuleSourceSourceLogsConfigurationArgs
                {
                    EncryptedLogGroupStrategy = "SKIP",
                    LogGroupSelectionCriteria = "*",
                },
            },
        },
        Tags = 
        {
            { "Name", "example-centralization-rule" },
            { "Environment", "production" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetCallerIdentityArgs;
import com.pulumi.aws.organizations.OrganizationsFunctions;
import com.pulumi.aws.observabilityadmin.CentralizationRuleForOrganization;
import com.pulumi.aws.observabilityadmin.CentralizationRuleForOrganizationArgs;
import com.pulumi.aws.observabilityadmin.inputs.CentralizationRuleForOrganizationRuleArgs;
import com.pulumi.aws.observabilityadmin.inputs.CentralizationRuleForOrganizationRuleDestinationArgs;
import com.pulumi.aws.observabilityadmin.inputs.CentralizationRuleForOrganizationRuleSourceArgs;
import com.pulumi.aws.observabilityadmin.inputs.CentralizationRuleForOrganizationRuleSourceSourceLogsConfigurationArgs;
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 current = AwsFunctions.getCallerIdentity(GetCallerIdentityArgs.builder()
            .build());

        final var currentGetOrganization = OrganizationsFunctions.getOrganization(%!v(PANIC=Format method: runtime error: invalid memory address or nil pointer dereference);

        var example = new CentralizationRuleForOrganization("example", CentralizationRuleForOrganizationArgs.builder()
            .ruleName("example-centralization-rule")
            .rule(CentralizationRuleForOrganizationRuleArgs.builder()
                .destination(CentralizationRuleForOrganizationRuleDestinationArgs.builder()
                    .region("eu-west-1")
                    .account(current.accountId())
                    .build())
                .source(CentralizationRuleForOrganizationRuleSourceArgs.builder()
                    .regions("ap-southeast-1")
                    .scope(String.format("OrganizationId = '%s'", currentGetOrganization.id()))
                    .sourceLogsConfiguration(CentralizationRuleForOrganizationRuleSourceSourceLogsConfigurationArgs.builder()
                        .encryptedLogGroupStrategy("SKIP")
                        .logGroupSelectionCriteria("*")
                        .build())
                    .build())
                .build())
            .tags(Map.ofEntries(
                Map.entry("Name", "example-centralization-rule"),
                Map.entry("Environment", "production")
            ))
            .build());

    }
}
resources:
  example:
    type: aws:observabilityadmin:CentralizationRuleForOrganization
    properties:
      ruleName: example-centralization-rule
      rule:
        destination:
          region: eu-west-1
          account: ${current.accountId}
        source:
          regions:
            - ap-southeast-1
          scope: OrganizationId = '${currentGetOrganization.id}'
          sourceLogsConfiguration:
            encryptedLogGroupStrategy: SKIP
            logGroupSelectionCriteria: '*'
      tags:
        Name: example-centralization-rule
        Environment: production
variables:
  current:
    fn::invoke:
      function: aws:getCallerIdentity
      arguments: {}
  currentGetOrganization:
    fn::invoke:
      function: aws:organizations:getOrganization
      arguments: {}

The rule defines where logs flow: the destination block specifies the target account and region, while the source block identifies which regions and accounts to collect from. The scope property uses an organization ID to apply the rule across all member accounts. The sourceLogsConfiguration controls how encrypted log groups are handled; setting encryptedLogGroupStrategy to “SKIP” excludes encrypted logs, while “ALLOW” includes them. The logGroupSelectionCriteria wildcard “*” collects all log groups.

Filter logs by log group name patterns

When centralizing logs, teams often collect only specific log groups to reduce storage costs and focus on relevant data.

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

const current = aws.getCallerIdentity({});
const currentGetOrganization = aws.organizations.getOrganization({});
const filtered = new aws.observabilityadmin.CentralizationRuleForOrganization("filtered", {
    ruleName: "filtered-centralization-rule",
    rule: {
        destination: {
            region: "eu-west-1",
            account: current.then(current => current.accountId),
        },
        source: {
            regions: [
                "ap-southeast-1",
                "us-east-1",
            ],
            scope: currentGetOrganization.then(currentGetOrganization => `OrganizationId = '${currentGetOrganization.id}'`),
            sourceLogsConfiguration: {
                encryptedLogGroupStrategy: "ALLOW",
                logGroupSelectionCriteria: "LogGroupName LIKE '/aws/lambda%'",
            },
        },
    },
    tags: {
        Name: "filtered-centralization-rule",
        Filter: "lambda-logs",
    },
});
import pulumi
import pulumi_aws as aws

current = aws.get_caller_identity()
current_get_organization = aws.organizations.get_organization()
filtered = aws.observabilityadmin.CentralizationRuleForOrganization("filtered",
    rule_name="filtered-centralization-rule",
    rule={
        "destination": {
            "region": "eu-west-1",
            "account": current.account_id,
        },
        "source": {
            "regions": [
                "ap-southeast-1",
                "us-east-1",
            ],
            "scope": f"OrganizationId = '{current_get_organization.id}'",
            "source_logs_configuration": {
                "encrypted_log_group_strategy": "ALLOW",
                "log_group_selection_criteria": "LogGroupName LIKE '/aws/lambda%'",
            },
        },
    },
    tags={
        "Name": "filtered-centralization-rule",
        "Filter": "lambda-logs",
    })
package main

import (
	"fmt"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/observabilityadmin"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/organizations"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		current, err := aws.GetCallerIdentity(ctx, &aws.GetCallerIdentityArgs{}, nil)
		if err != nil {
			return err
		}
		currentGetOrganization, err := organizations.LookupOrganization(ctx, map[string]interface{}{}, nil)
		if err != nil {
			return err
		}
		_, err = observabilityadmin.NewCentralizationRuleForOrganization(ctx, "filtered", &observabilityadmin.CentralizationRuleForOrganizationArgs{
			RuleName: pulumi.String("filtered-centralization-rule"),
			Rule: &observabilityadmin.CentralizationRuleForOrganizationRuleArgs{
				Destination: &observabilityadmin.CentralizationRuleForOrganizationRuleDestinationArgs{
					Region:  pulumi.String("eu-west-1"),
					Account: pulumi.String(current.AccountId),
				},
				Source: &observabilityadmin.CentralizationRuleForOrganizationRuleSourceArgs{
					Regions: pulumi.StringArray{
						pulumi.String("ap-southeast-1"),
						pulumi.String("us-east-1"),
					},
					Scope: pulumi.Sprintf("OrganizationId = '%v'", currentGetOrganization.Id),
					SourceLogsConfiguration: &observabilityadmin.CentralizationRuleForOrganizationRuleSourceSourceLogsConfigurationArgs{
						EncryptedLogGroupStrategy: pulumi.String("ALLOW"),
						LogGroupSelectionCriteria: pulumi.String("LogGroupName LIKE '/aws/lambda%'"),
					},
				},
			},
			Tags: pulumi.StringMap{
				"Name":   pulumi.String("filtered-centralization-rule"),
				"Filter": pulumi.String("lambda-logs"),
			},
		})
		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 current = Aws.GetCallerIdentity.Invoke();

    var currentGetOrganization = Aws.Organizations.GetOrganization.Invoke();

    var filtered = new Aws.Observabilityadmin.CentralizationRuleForOrganization("filtered", new()
    {
        RuleName = "filtered-centralization-rule",
        Rule = new Aws.Observabilityadmin.Inputs.CentralizationRuleForOrganizationRuleArgs
        {
            Destination = new Aws.Observabilityadmin.Inputs.CentralizationRuleForOrganizationRuleDestinationArgs
            {
                Region = "eu-west-1",
                Account = current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId),
            },
            Source = new Aws.Observabilityadmin.Inputs.CentralizationRuleForOrganizationRuleSourceArgs
            {
                Regions = new[]
                {
                    "ap-southeast-1",
                    "us-east-1",
                },
                Scope = $"OrganizationId = '{currentGetOrganization.Apply(getOrganizationResult => getOrganizationResult.Id)}'",
                SourceLogsConfiguration = new Aws.Observabilityadmin.Inputs.CentralizationRuleForOrganizationRuleSourceSourceLogsConfigurationArgs
                {
                    EncryptedLogGroupStrategy = "ALLOW",
                    LogGroupSelectionCriteria = "LogGroupName LIKE '/aws/lambda%'",
                },
            },
        },
        Tags = 
        {
            { "Name", "filtered-centralization-rule" },
            { "Filter", "lambda-logs" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetCallerIdentityArgs;
import com.pulumi.aws.organizations.OrganizationsFunctions;
import com.pulumi.aws.observabilityadmin.CentralizationRuleForOrganization;
import com.pulumi.aws.observabilityadmin.CentralizationRuleForOrganizationArgs;
import com.pulumi.aws.observabilityadmin.inputs.CentralizationRuleForOrganizationRuleArgs;
import com.pulumi.aws.observabilityadmin.inputs.CentralizationRuleForOrganizationRuleDestinationArgs;
import com.pulumi.aws.observabilityadmin.inputs.CentralizationRuleForOrganizationRuleSourceArgs;
import com.pulumi.aws.observabilityadmin.inputs.CentralizationRuleForOrganizationRuleSourceSourceLogsConfigurationArgs;
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 current = AwsFunctions.getCallerIdentity(GetCallerIdentityArgs.builder()
            .build());

        final var currentGetOrganization = OrganizationsFunctions.getOrganization(%!v(PANIC=Format method: runtime error: invalid memory address or nil pointer dereference);

        var filtered = new CentralizationRuleForOrganization("filtered", CentralizationRuleForOrganizationArgs.builder()
            .ruleName("filtered-centralization-rule")
            .rule(CentralizationRuleForOrganizationRuleArgs.builder()
                .destination(CentralizationRuleForOrganizationRuleDestinationArgs.builder()
                    .region("eu-west-1")
                    .account(current.accountId())
                    .build())
                .source(CentralizationRuleForOrganizationRuleSourceArgs.builder()
                    .regions(                    
                        "ap-southeast-1",
                        "us-east-1")
                    .scope(String.format("OrganizationId = '%s'", currentGetOrganization.id()))
                    .sourceLogsConfiguration(CentralizationRuleForOrganizationRuleSourceSourceLogsConfigurationArgs.builder()
                        .encryptedLogGroupStrategy("ALLOW")
                        .logGroupSelectionCriteria("LogGroupName LIKE '/aws/lambda%'")
                        .build())
                    .build())
                .build())
            .tags(Map.ofEntries(
                Map.entry("Name", "filtered-centralization-rule"),
                Map.entry("Filter", "lambda-logs")
            ))
            .build());

    }
}
resources:
  filtered:
    type: aws:observabilityadmin:CentralizationRuleForOrganization
    properties:
      ruleName: filtered-centralization-rule
      rule:
        destination:
          region: eu-west-1
          account: ${current.accountId}
        source:
          regions:
            - ap-southeast-1
            - us-east-1
          scope: OrganizationId = '${currentGetOrganization.id}'
          sourceLogsConfiguration:
            encryptedLogGroupStrategy: ALLOW
            logGroupSelectionCriteria: LogGroupName LIKE '/aws/lambda%'
      tags:
        Name: filtered-centralization-rule
        Filter: lambda-logs
variables:
  current:
    fn::invoke:
      function: aws:getCallerIdentity
      arguments: {}
  currentGetOrganization:
    fn::invoke:
      function: aws:organizations:getOrganization
      arguments: {}

The logGroupSelectionCriteria property accepts SQL-like patterns to filter which log groups are centralized. Here, LogGroupName LIKE '/aws/lambda%' collects only Lambda function logs. This filtering happens at the source before logs are transmitted, reducing network transfer and storage costs in the destination account.

Add encryption and backup regions for resilience

Production log centralization requires encryption at rest and backup regions for disaster recovery.

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

const current = aws.getCallerIdentity({});
const currentGetOrganization = aws.organizations.getOrganization({});
const advanced = new aws.observabilityadmin.CentralizationRuleForOrganization("advanced", {
    ruleName: "advanced-centralization-rule",
    rule: {
        destination: {
            region: "eu-west-1",
            account: current.then(current => current.accountId),
            destinationLogsConfiguration: {
                logsEncryptionConfiguration: {
                    encryptionStrategy: "AWS_OWNED",
                },
                backupConfiguration: {
                    region: "us-west-1",
                },
            },
        },
        source: {
            regions: [
                "ap-southeast-1",
                "us-east-1",
            ],
            scope: currentGetOrganization.then(currentGetOrganization => `OrganizationId = '${currentGetOrganization.id}'`),
            sourceLogsConfiguration: {
                encryptedLogGroupStrategy: "ALLOW",
                logGroupSelectionCriteria: "*",
            },
        },
    },
    tags: {
        Name: "advanced-centralization-rule",
        Environment: "production",
        Team: "observability",
    },
});
import pulumi
import pulumi_aws as aws

current = aws.get_caller_identity()
current_get_organization = aws.organizations.get_organization()
advanced = aws.observabilityadmin.CentralizationRuleForOrganization("advanced",
    rule_name="advanced-centralization-rule",
    rule={
        "destination": {
            "region": "eu-west-1",
            "account": current.account_id,
            "destination_logs_configuration": {
                "logs_encryption_configuration": {
                    "encryption_strategy": "AWS_OWNED",
                },
                "backup_configuration": {
                    "region": "us-west-1",
                },
            },
        },
        "source": {
            "regions": [
                "ap-southeast-1",
                "us-east-1",
            ],
            "scope": f"OrganizationId = '{current_get_organization.id}'",
            "source_logs_configuration": {
                "encrypted_log_group_strategy": "ALLOW",
                "log_group_selection_criteria": "*",
            },
        },
    },
    tags={
        "Name": "advanced-centralization-rule",
        "Environment": "production",
        "Team": "observability",
    })
package main

import (
	"fmt"

	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/observabilityadmin"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/organizations"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		current, err := aws.GetCallerIdentity(ctx, &aws.GetCallerIdentityArgs{}, nil)
		if err != nil {
			return err
		}
		currentGetOrganization, err := organizations.LookupOrganization(ctx, map[string]interface{}{}, nil)
		if err != nil {
			return err
		}
		_, err = observabilityadmin.NewCentralizationRuleForOrganization(ctx, "advanced", &observabilityadmin.CentralizationRuleForOrganizationArgs{
			RuleName: pulumi.String("advanced-centralization-rule"),
			Rule: &observabilityadmin.CentralizationRuleForOrganizationRuleArgs{
				Destination: &observabilityadmin.CentralizationRuleForOrganizationRuleDestinationArgs{
					Region:  pulumi.String("eu-west-1"),
					Account: pulumi.String(current.AccountId),
					DestinationLogsConfiguration: &observabilityadmin.CentralizationRuleForOrganizationRuleDestinationDestinationLogsConfigurationArgs{
						LogsEncryptionConfiguration: &observabilityadmin.CentralizationRuleForOrganizationRuleDestinationDestinationLogsConfigurationLogsEncryptionConfigurationArgs{
							EncryptionStrategy: pulumi.String("AWS_OWNED"),
						},
						BackupConfiguration: &observabilityadmin.CentralizationRuleForOrganizationRuleDestinationDestinationLogsConfigurationBackupConfigurationArgs{
							Region: pulumi.String("us-west-1"),
						},
					},
				},
				Source: &observabilityadmin.CentralizationRuleForOrganizationRuleSourceArgs{
					Regions: pulumi.StringArray{
						pulumi.String("ap-southeast-1"),
						pulumi.String("us-east-1"),
					},
					Scope: pulumi.Sprintf("OrganizationId = '%v'", currentGetOrganization.Id),
					SourceLogsConfiguration: &observabilityadmin.CentralizationRuleForOrganizationRuleSourceSourceLogsConfigurationArgs{
						EncryptedLogGroupStrategy: pulumi.String("ALLOW"),
						LogGroupSelectionCriteria: pulumi.String("*"),
					},
				},
			},
			Tags: pulumi.StringMap{
				"Name":        pulumi.String("advanced-centralization-rule"),
				"Environment": pulumi.String("production"),
				"Team":        pulumi.String("observability"),
			},
		})
		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 current = Aws.GetCallerIdentity.Invoke();

    var currentGetOrganization = Aws.Organizations.GetOrganization.Invoke();

    var advanced = new Aws.Observabilityadmin.CentralizationRuleForOrganization("advanced", new()
    {
        RuleName = "advanced-centralization-rule",
        Rule = new Aws.Observabilityadmin.Inputs.CentralizationRuleForOrganizationRuleArgs
        {
            Destination = new Aws.Observabilityadmin.Inputs.CentralizationRuleForOrganizationRuleDestinationArgs
            {
                Region = "eu-west-1",
                Account = current.Apply(getCallerIdentityResult => getCallerIdentityResult.AccountId),
                DestinationLogsConfiguration = new Aws.Observabilityadmin.Inputs.CentralizationRuleForOrganizationRuleDestinationDestinationLogsConfigurationArgs
                {
                    LogsEncryptionConfiguration = new Aws.Observabilityadmin.Inputs.CentralizationRuleForOrganizationRuleDestinationDestinationLogsConfigurationLogsEncryptionConfigurationArgs
                    {
                        EncryptionStrategy = "AWS_OWNED",
                    },
                    BackupConfiguration = new Aws.Observabilityadmin.Inputs.CentralizationRuleForOrganizationRuleDestinationDestinationLogsConfigurationBackupConfigurationArgs
                    {
                        Region = "us-west-1",
                    },
                },
            },
            Source = new Aws.Observabilityadmin.Inputs.CentralizationRuleForOrganizationRuleSourceArgs
            {
                Regions = new[]
                {
                    "ap-southeast-1",
                    "us-east-1",
                },
                Scope = $"OrganizationId = '{currentGetOrganization.Apply(getOrganizationResult => getOrganizationResult.Id)}'",
                SourceLogsConfiguration = new Aws.Observabilityadmin.Inputs.CentralizationRuleForOrganizationRuleSourceSourceLogsConfigurationArgs
                {
                    EncryptedLogGroupStrategy = "ALLOW",
                    LogGroupSelectionCriteria = "*",
                },
            },
        },
        Tags = 
        {
            { "Name", "advanced-centralization-rule" },
            { "Environment", "production" },
            { "Team", "observability" },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.AwsFunctions;
import com.pulumi.aws.inputs.GetCallerIdentityArgs;
import com.pulumi.aws.organizations.OrganizationsFunctions;
import com.pulumi.aws.observabilityadmin.CentralizationRuleForOrganization;
import com.pulumi.aws.observabilityadmin.CentralizationRuleForOrganizationArgs;
import com.pulumi.aws.observabilityadmin.inputs.CentralizationRuleForOrganizationRuleArgs;
import com.pulumi.aws.observabilityadmin.inputs.CentralizationRuleForOrganizationRuleDestinationArgs;
import com.pulumi.aws.observabilityadmin.inputs.CentralizationRuleForOrganizationRuleDestinationDestinationLogsConfigurationArgs;
import com.pulumi.aws.observabilityadmin.inputs.CentralizationRuleForOrganizationRuleDestinationDestinationLogsConfigurationLogsEncryptionConfigurationArgs;
import com.pulumi.aws.observabilityadmin.inputs.CentralizationRuleForOrganizationRuleDestinationDestinationLogsConfigurationBackupConfigurationArgs;
import com.pulumi.aws.observabilityadmin.inputs.CentralizationRuleForOrganizationRuleSourceArgs;
import com.pulumi.aws.observabilityadmin.inputs.CentralizationRuleForOrganizationRuleSourceSourceLogsConfigurationArgs;
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 current = AwsFunctions.getCallerIdentity(GetCallerIdentityArgs.builder()
            .build());

        final var currentGetOrganization = OrganizationsFunctions.getOrganization(%!v(PANIC=Format method: runtime error: invalid memory address or nil pointer dereference);

        var advanced = new CentralizationRuleForOrganization("advanced", CentralizationRuleForOrganizationArgs.builder()
            .ruleName("advanced-centralization-rule")
            .rule(CentralizationRuleForOrganizationRuleArgs.builder()
                .destination(CentralizationRuleForOrganizationRuleDestinationArgs.builder()
                    .region("eu-west-1")
                    .account(current.accountId())
                    .destinationLogsConfiguration(CentralizationRuleForOrganizationRuleDestinationDestinationLogsConfigurationArgs.builder()
                        .logsEncryptionConfiguration(CentralizationRuleForOrganizationRuleDestinationDestinationLogsConfigurationLogsEncryptionConfigurationArgs.builder()
                            .encryptionStrategy("AWS_OWNED")
                            .build())
                        .backupConfiguration(CentralizationRuleForOrganizationRuleDestinationDestinationLogsConfigurationBackupConfigurationArgs.builder()
                            .region("us-west-1")
                            .build())
                        .build())
                    .build())
                .source(CentralizationRuleForOrganizationRuleSourceArgs.builder()
                    .regions(                    
                        "ap-southeast-1",
                        "us-east-1")
                    .scope(String.format("OrganizationId = '%s'", currentGetOrganization.id()))
                    .sourceLogsConfiguration(CentralizationRuleForOrganizationRuleSourceSourceLogsConfigurationArgs.builder()
                        .encryptedLogGroupStrategy("ALLOW")
                        .logGroupSelectionCriteria("*")
                        .build())
                    .build())
                .build())
            .tags(Map.ofEntries(
                Map.entry("Name", "advanced-centralization-rule"),
                Map.entry("Environment", "production"),
                Map.entry("Team", "observability")
            ))
            .build());

    }
}
resources:
  advanced:
    type: aws:observabilityadmin:CentralizationRuleForOrganization
    properties:
      ruleName: advanced-centralization-rule
      rule:
        destination:
          region: eu-west-1
          account: ${current.accountId}
          destinationLogsConfiguration:
            logsEncryptionConfiguration:
              encryptionStrategy: AWS_OWNED
            backupConfiguration:
              region: us-west-1
        source:
          regions:
            - ap-southeast-1
            - us-east-1
          scope: OrganizationId = '${currentGetOrganization.id}'
          sourceLogsConfiguration:
            encryptedLogGroupStrategy: ALLOW
            logGroupSelectionCriteria: '*'
      tags:
        Name: advanced-centralization-rule
        Environment: production
        Team: observability
variables:
  current:
    fn::invoke:
      function: aws:getCallerIdentity
      arguments: {}
  currentGetOrganization:
    fn::invoke:
      function: aws:organizations:getOrganization
      arguments: {}

The destinationLogsConfiguration block adds encryption and backup capabilities. The logsEncryptionConfiguration specifies how logs are encrypted in the destination; “AWS_OWNED” uses AWS-managed keys. The backupConfiguration defines a secondary region where logs are replicated for disaster recovery. This configuration extends basic centralization with production-grade resilience and compliance features.

Beyond these examples

These snippets focus on specific centralization rule features: cross-region and cross-account log centralization, log group filtering and encryption, and backup region configuration. They’re intentionally minimal rather than full observability solutions.

The examples rely on pre-existing infrastructure such as AWS Organizations with delegated administrator permissions and destination accounts with appropriate IAM permissions. They focus on configuring the centralization rule rather than provisioning the surrounding IAM and organizational infrastructure.

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

  • IAM role and permission setup for centralization
  • Destination log group configuration and retention
  • Cost optimization strategies for centralized logs
  • Monitoring and alerting on centralization failures

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

Let's configure AWS CloudWatch Observability Centralization Rules

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Prerequisites & Setup
What permissions do I need to create a centralization rule?
You need an AWS account within an organization with delegated administrator permissions.
Can I use the same rule name across different organizations?
No, the ruleName must be unique within your organization.
Log Source Configuration
How do I specify which accounts to centralize logs from?
Use the scope parameter with an OrganizationId filter to target accounts within your organization, as shown in all examples.
Can I centralize logs from multiple regions?
Yes, specify multiple regions in the source.regions array.
How do I handle encrypted log groups?
Set encryptedLogGroupStrategy to SKIP to ignore encrypted log groups or ALLOW to include them in centralization.
How do I filter which log groups get centralized?
Use logGroupSelectionCriteria with * for all logs or LIKE syntax for filtering (e.g., LogGroupName LIKE '/aws/lambda%' for Lambda logs only).
Destination & Storage
How do I encrypt centralized logs in the destination?
Configure destinationLogsConfiguration.logsEncryptionConfiguration.encryptionStrategy with a value like AWS_OWNED.
Can I set up a backup region for centralized logs?
Yes, configure destinationLogsConfiguration.backupConfiguration.region with your backup region.
What's required for the destination configuration?
You must specify both destination.region and destination.account to define where logs will be centralized.

Using a different cloud?

Explore monitoring guides for other cloud providers: