Configure AWS Access Analyzer

The aws:accessanalyzer/analyzer:Analyzer resource, part of the Pulumi AWS provider, defines an Access Analyzer that continuously scans AWS resources to identify external access or unused permissions. This guide focuses on three capabilities: account and organization-level analysis, unused access detection with filtering, and internal access monitoring with resource targeting.

Organization analyzers require AWS Organizations with the Access Analyzer service enabled. Internal and unused access analyzers are organization-scoped features. The examples are intentionally small. Combine them with your own archive rules, notifications, and tagging strategy.

Analyze access within a single AWS account

Teams starting with Access Analyzer typically scan resources in a single account to identify external access grants, providing visibility into S3 buckets, IAM roles, and other resources shared outside the account boundary.

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

const example = new aws.accessanalyzer.Analyzer("example", {analyzerName: "example"});
import pulumi
import pulumi_aws as aws

example = aws.accessanalyzer.Analyzer("example", analyzer_name="example")
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := accessanalyzer.NewAnalyzer(ctx, "example", &accessanalyzer.AnalyzerArgs{
			AnalyzerName: pulumi.String("example"),
		})
		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.AccessAnalyzer.Analyzer("example", new()
    {
        AnalyzerName = "example",
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.accessanalyzer.Analyzer;
import com.pulumi.aws.accessanalyzer.AnalyzerArgs;
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 Analyzer("example", AnalyzerArgs.builder()
            .analyzerName("example")
            .build());

    }
}
resources:
  example:
    type: aws:accessanalyzer:Analyzer
    properties:
      analyzerName: example

When you create an analyzer without specifying a type, it defaults to ACCOUNT scope. The analyzer continuously scans supported resources in the account and generates findings when it detects access granted to external principals. The analyzerName property sets a unique identifier for the analyzer.

Scan all accounts in an AWS Organization

Organizations with multiple accounts need centralized visibility into access patterns across the entire organization.

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

const example = new aws.organizations.Organization("example", {awsServiceAccessPrincipals: ["access-analyzer.amazonaws.com"]});
const exampleAnalyzer = new aws.accessanalyzer.Analyzer("example", {
    analyzerName: "example",
    type: "ORGANIZATION",
}, {
    dependsOn: [example],
});
import pulumi
import pulumi_aws as aws

example = aws.organizations.Organization("example", aws_service_access_principals=["access-analyzer.amazonaws.com"])
example_analyzer = aws.accessanalyzer.Analyzer("example",
    analyzer_name="example",
    type="ORGANIZATION",
    opts = pulumi.ResourceOptions(depends_on=[example]))
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/accessanalyzer"
	"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 {
		example, err := organizations.NewOrganization(ctx, "example", &organizations.OrganizationArgs{
			AwsServiceAccessPrincipals: pulumi.StringArray{
				pulumi.String("access-analyzer.amazonaws.com"),
			},
		})
		if err != nil {
			return err
		}
		_, err = accessanalyzer.NewAnalyzer(ctx, "example", &accessanalyzer.AnalyzerArgs{
			AnalyzerName: pulumi.String("example"),
			Type:         pulumi.String("ORGANIZATION"),
		}, pulumi.DependsOn([]pulumi.Resource{
			example,
		}))
		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.Organizations.Organization("example", new()
    {
        AwsServiceAccessPrincipals = new[]
        {
            "access-analyzer.amazonaws.com",
        },
    });

    var exampleAnalyzer = new Aws.AccessAnalyzer.Analyzer("example", new()
    {
        AnalyzerName = "example",
        Type = "ORGANIZATION",
    }, new CustomResourceOptions
    {
        DependsOn =
        {
            example,
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.organizations.Organization;
import com.pulumi.aws.organizations.OrganizationArgs;
import com.pulumi.aws.accessanalyzer.Analyzer;
import com.pulumi.aws.accessanalyzer.AnalyzerArgs;
import com.pulumi.resources.CustomResourceOptions;
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 Organization("example", OrganizationArgs.builder()
            .awsServiceAccessPrincipals("access-analyzer.amazonaws.com")
            .build());

        var exampleAnalyzer = new Analyzer("exampleAnalyzer", AnalyzerArgs.builder()
            .analyzerName("example")
            .type("ORGANIZATION")
            .build(), CustomResourceOptions.builder()
                .dependsOn(example)
                .build());

    }
}
resources:
  example:
    type: aws:organizations:Organization
    properties:
      awsServiceAccessPrincipals:
        - access-analyzer.amazonaws.com
  exampleAnalyzer:
    type: aws:accessanalyzer:Analyzer
    name: example
    properties:
      analyzerName: example
      type: ORGANIZATION
    options:
      dependsOn:
        - ${example}

Setting type to ORGANIZATION creates an analyzer that scans all member accounts from the management account. The dependsOn property ensures the Organizations service access is enabled before creating the analyzer. The awsServiceAccessPrincipals property grants Access Analyzer permission to read resources across all organization accounts.

Identify unused permissions with exclusion rules

Security teams often need to find IAM permissions that haven’t been used recently, but want to exclude certain accounts or resources from analysis to reduce noise.

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

const example = new aws.accessanalyzer.Analyzer("example", {
    analyzerName: "example",
    type: "ORGANIZATION_UNUSED_ACCESS",
    configuration: {
        unusedAccess: {
            unusedAccessAge: 180,
            analysisRule: {
                exclusions: [
                    {
                        accountIds: [
                            "123456789012",
                            "234567890123",
                        ],
                    },
                    {
                        resourceTags: [
                            {
                                key1: "value1",
                            },
                            {
                                key2: "value2",
                            },
                        ],
                    },
                ],
            },
        },
    },
});
import pulumi
import pulumi_aws as aws

example = aws.accessanalyzer.Analyzer("example",
    analyzer_name="example",
    type="ORGANIZATION_UNUSED_ACCESS",
    configuration={
        "unused_access": {
            "unused_access_age": 180,
            "analysis_rule": {
                "exclusions": [
                    {
                        "account_ids": [
                            "123456789012",
                            "234567890123",
                        ],
                    },
                    {
                        "resource_tags": [
                            {
                                "key1": "value1",
                            },
                            {
                                "key2": "value2",
                            },
                        ],
                    },
                ],
            },
        },
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := accessanalyzer.NewAnalyzer(ctx, "example", &accessanalyzer.AnalyzerArgs{
			AnalyzerName: pulumi.String("example"),
			Type:         pulumi.String("ORGANIZATION_UNUSED_ACCESS"),
			Configuration: &accessanalyzer.AnalyzerConfigurationArgs{
				UnusedAccess: &accessanalyzer.AnalyzerConfigurationUnusedAccessArgs{
					UnusedAccessAge: pulumi.Int(180),
					AnalysisRule: &accessanalyzer.AnalyzerConfigurationUnusedAccessAnalysisRuleArgs{
						Exclusions: accessanalyzer.AnalyzerConfigurationUnusedAccessAnalysisRuleExclusionArray{
							&accessanalyzer.AnalyzerConfigurationUnusedAccessAnalysisRuleExclusionArgs{
								AccountIds: pulumi.StringArray{
									pulumi.String("123456789012"),
									pulumi.String("234567890123"),
								},
							},
							&accessanalyzer.AnalyzerConfigurationUnusedAccessAnalysisRuleExclusionArgs{
								ResourceTags: pulumi.StringMapArray{
									pulumi.StringMap{
										"key1": pulumi.String("value1"),
									},
									pulumi.StringMap{
										"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.AccessAnalyzer.Analyzer("example", new()
    {
        AnalyzerName = "example",
        Type = "ORGANIZATION_UNUSED_ACCESS",
        Configuration = new Aws.AccessAnalyzer.Inputs.AnalyzerConfigurationArgs
        {
            UnusedAccess = new Aws.AccessAnalyzer.Inputs.AnalyzerConfigurationUnusedAccessArgs
            {
                UnusedAccessAge = 180,
                AnalysisRule = new Aws.AccessAnalyzer.Inputs.AnalyzerConfigurationUnusedAccessAnalysisRuleArgs
                {
                    Exclusions = new[]
                    {
                        new Aws.AccessAnalyzer.Inputs.AnalyzerConfigurationUnusedAccessAnalysisRuleExclusionArgs
                        {
                            AccountIds = new[]
                            {
                                "123456789012",
                                "234567890123",
                            },
                        },
                        new Aws.AccessAnalyzer.Inputs.AnalyzerConfigurationUnusedAccessAnalysisRuleExclusionArgs
                        {
                            ResourceTags = new[]
                            {
                                
                                {
                                    { "key1", "value1" },
                                },
                                
                                {
                                    { "key2", "value2" },
                                },
                            },
                        },
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.accessanalyzer.Analyzer;
import com.pulumi.aws.accessanalyzer.AnalyzerArgs;
import com.pulumi.aws.accessanalyzer.inputs.AnalyzerConfigurationArgs;
import com.pulumi.aws.accessanalyzer.inputs.AnalyzerConfigurationUnusedAccessArgs;
import com.pulumi.aws.accessanalyzer.inputs.AnalyzerConfigurationUnusedAccessAnalysisRuleArgs;
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 Analyzer("example", AnalyzerArgs.builder()
            .analyzerName("example")
            .type("ORGANIZATION_UNUSED_ACCESS")
            .configuration(AnalyzerConfigurationArgs.builder()
                .unusedAccess(AnalyzerConfigurationUnusedAccessArgs.builder()
                    .unusedAccessAge(180)
                    .analysisRule(AnalyzerConfigurationUnusedAccessAnalysisRuleArgs.builder()
                        .exclusions(                        
                            AnalyzerConfigurationUnusedAccessAnalysisRuleExclusionArgs.builder()
                                .accountIds(                                
                                    "123456789012",
                                    "234567890123")
                                .build(),
                            AnalyzerConfigurationUnusedAccessAnalysisRuleExclusionArgs.builder()
                                .resourceTags(                                
                                    Map.of("key1", "value1"),
                                    Map.of("key2", "value2"))
                                .build())
                        .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  example:
    type: aws:accessanalyzer:Analyzer
    properties:
      analyzerName: example
      type: ORGANIZATION_UNUSED_ACCESS
      configuration:
        unusedAccess:
          unusedAccessAge: 180
          analysisRule:
            exclusions:
              - accountIds:
                  - '123456789012'
                  - '234567890123'
              - resourceTags:
                  - key1: value1
                  - key2: value2

The ORGANIZATION_UNUSED_ACCESS type enables unused access detection. The configuration block defines analysis rules: unusedAccessAge sets the threshold (180 days here), and exclusions filter out specific accounts or resources by tags. This helps focus findings on actionable unused permissions while ignoring known exceptions.

Monitor internal access for specific resource types

Organizations tracking access within their trust zone often focus on specific resource types like S3 buckets, RDS snapshots, or DynamoDB tables rather than analyzing all resource types.

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

const test = new aws.accessanalyzer.Analyzer("test", {
    analyzerName: "example",
    type: "ORGANIZATION_INTERNAL_ACCESS",
    configuration: {
        internalAccess: {
            analysisRule: {
                inclusions: [{
                    resourceTypes: [
                        "AWS::S3::Bucket",
                        "AWS::RDS::DBSnapshot",
                        "AWS::DynamoDB::Table",
                    ],
                }],
            },
        },
    },
});
import pulumi
import pulumi_aws as aws

test = aws.accessanalyzer.Analyzer("test",
    analyzer_name="example",
    type="ORGANIZATION_INTERNAL_ACCESS",
    configuration={
        "internal_access": {
            "analysis_rule": {
                "inclusions": [{
                    "resource_types": [
                        "AWS::S3::Bucket",
                        "AWS::RDS::DBSnapshot",
                        "AWS::DynamoDB::Table",
                    ],
                }],
            },
        },
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := accessanalyzer.NewAnalyzer(ctx, "test", &accessanalyzer.AnalyzerArgs{
			AnalyzerName: pulumi.String("example"),
			Type:         pulumi.String("ORGANIZATION_INTERNAL_ACCESS"),
			Configuration: &accessanalyzer.AnalyzerConfigurationArgs{
				InternalAccess: &accessanalyzer.AnalyzerConfigurationInternalAccessArgs{
					AnalysisRule: &accessanalyzer.AnalyzerConfigurationInternalAccessAnalysisRuleArgs{
						Inclusions: accessanalyzer.AnalyzerConfigurationInternalAccessAnalysisRuleInclusionArray{
							&accessanalyzer.AnalyzerConfigurationInternalAccessAnalysisRuleInclusionArgs{
								ResourceTypes: pulumi.StringArray{
									pulumi.String("AWS::S3::Bucket"),
									pulumi.String("AWS::RDS::DBSnapshot"),
									pulumi.String("AWS::DynamoDB::Table"),
								},
							},
						},
					},
				},
			},
		})
		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 test = new Aws.AccessAnalyzer.Analyzer("test", new()
    {
        AnalyzerName = "example",
        Type = "ORGANIZATION_INTERNAL_ACCESS",
        Configuration = new Aws.AccessAnalyzer.Inputs.AnalyzerConfigurationArgs
        {
            InternalAccess = new Aws.AccessAnalyzer.Inputs.AnalyzerConfigurationInternalAccessArgs
            {
                AnalysisRule = new Aws.AccessAnalyzer.Inputs.AnalyzerConfigurationInternalAccessAnalysisRuleArgs
                {
                    Inclusions = new[]
                    {
                        new Aws.AccessAnalyzer.Inputs.AnalyzerConfigurationInternalAccessAnalysisRuleInclusionArgs
                        {
                            ResourceTypes = new[]
                            {
                                "AWS::S3::Bucket",
                                "AWS::RDS::DBSnapshot",
                                "AWS::DynamoDB::Table",
                            },
                        },
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.accessanalyzer.Analyzer;
import com.pulumi.aws.accessanalyzer.AnalyzerArgs;
import com.pulumi.aws.accessanalyzer.inputs.AnalyzerConfigurationArgs;
import com.pulumi.aws.accessanalyzer.inputs.AnalyzerConfigurationInternalAccessArgs;
import com.pulumi.aws.accessanalyzer.inputs.AnalyzerConfigurationInternalAccessAnalysisRuleArgs;
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 test = new Analyzer("test", AnalyzerArgs.builder()
            .analyzerName("example")
            .type("ORGANIZATION_INTERNAL_ACCESS")
            .configuration(AnalyzerConfigurationArgs.builder()
                .internalAccess(AnalyzerConfigurationInternalAccessArgs.builder()
                    .analysisRule(AnalyzerConfigurationInternalAccessAnalysisRuleArgs.builder()
                        .inclusions(AnalyzerConfigurationInternalAccessAnalysisRuleInclusionArgs.builder()
                            .resourceTypes(                            
                                "AWS::S3::Bucket",
                                "AWS::RDS::DBSnapshot",
                                "AWS::DynamoDB::Table")
                            .build())
                        .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  test:
    type: aws:accessanalyzer:Analyzer
    properties:
      analyzerName: example
      type: ORGANIZATION_INTERNAL_ACCESS
      configuration:
        internalAccess:
          analysisRule:
            inclusions:
              - resourceTypes:
                  - AWS::S3::Bucket
                  - AWS::RDS::DBSnapshot
                  - AWS::DynamoDB::Table

The ORGANIZATION_INTERNAL_ACCESS type monitors access within the organization boundary. The inclusions block with resourceTypes filters analysis to specific AWS services. This reduces finding volume by focusing on high-value resource types.

Monitor internal access for specific resources

When teams need granular control over what’s analyzed, they can specify exact account IDs and resource ARNs rather than broad resource type filters.

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

const test = new aws.accessanalyzer.Analyzer("test", {
    analyzerName: "example",
    type: "ORGANIZATION_INTERNAL_ACCESS",
    configuration: {
        internalAccess: {
            analysisRule: {
                inclusions: [{
                    accountIds: ["123456789012"],
                    resourceArns: ["arn:aws:s3:::my-example-bucket"],
                }],
            },
        },
    },
});
import pulumi
import pulumi_aws as aws

test = aws.accessanalyzer.Analyzer("test",
    analyzer_name="example",
    type="ORGANIZATION_INTERNAL_ACCESS",
    configuration={
        "internal_access": {
            "analysis_rule": {
                "inclusions": [{
                    "account_ids": ["123456789012"],
                    "resource_arns": ["arn:aws:s3:::my-example-bucket"],
                }],
            },
        },
    })
package main

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

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		_, err := accessanalyzer.NewAnalyzer(ctx, "test", &accessanalyzer.AnalyzerArgs{
			AnalyzerName: pulumi.String("example"),
			Type:         pulumi.String("ORGANIZATION_INTERNAL_ACCESS"),
			Configuration: &accessanalyzer.AnalyzerConfigurationArgs{
				InternalAccess: &accessanalyzer.AnalyzerConfigurationInternalAccessArgs{
					AnalysisRule: &accessanalyzer.AnalyzerConfigurationInternalAccessAnalysisRuleArgs{
						Inclusions: accessanalyzer.AnalyzerConfigurationInternalAccessAnalysisRuleInclusionArray{
							&accessanalyzer.AnalyzerConfigurationInternalAccessAnalysisRuleInclusionArgs{
								AccountIds: pulumi.StringArray{
									pulumi.String("123456789012"),
								},
								ResourceArns: pulumi.StringArray{
									pulumi.String("arn:aws:s3:::my-example-bucket"),
								},
							},
						},
					},
				},
			},
		})
		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 test = new Aws.AccessAnalyzer.Analyzer("test", new()
    {
        AnalyzerName = "example",
        Type = "ORGANIZATION_INTERNAL_ACCESS",
        Configuration = new Aws.AccessAnalyzer.Inputs.AnalyzerConfigurationArgs
        {
            InternalAccess = new Aws.AccessAnalyzer.Inputs.AnalyzerConfigurationInternalAccessArgs
            {
                AnalysisRule = new Aws.AccessAnalyzer.Inputs.AnalyzerConfigurationInternalAccessAnalysisRuleArgs
                {
                    Inclusions = new[]
                    {
                        new Aws.AccessAnalyzer.Inputs.AnalyzerConfigurationInternalAccessAnalysisRuleInclusionArgs
                        {
                            AccountIds = new[]
                            {
                                "123456789012",
                            },
                            ResourceArns = new[]
                            {
                                "arn:aws:s3:::my-example-bucket",
                            },
                        },
                    },
                },
            },
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.accessanalyzer.Analyzer;
import com.pulumi.aws.accessanalyzer.AnalyzerArgs;
import com.pulumi.aws.accessanalyzer.inputs.AnalyzerConfigurationArgs;
import com.pulumi.aws.accessanalyzer.inputs.AnalyzerConfigurationInternalAccessArgs;
import com.pulumi.aws.accessanalyzer.inputs.AnalyzerConfigurationInternalAccessAnalysisRuleArgs;
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 test = new Analyzer("test", AnalyzerArgs.builder()
            .analyzerName("example")
            .type("ORGANIZATION_INTERNAL_ACCESS")
            .configuration(AnalyzerConfigurationArgs.builder()
                .internalAccess(AnalyzerConfigurationInternalAccessArgs.builder()
                    .analysisRule(AnalyzerConfigurationInternalAccessAnalysisRuleArgs.builder()
                        .inclusions(AnalyzerConfigurationInternalAccessAnalysisRuleInclusionArgs.builder()
                            .accountIds("123456789012")
                            .resourceArns("arn:aws:s3:::my-example-bucket")
                            .build())
                        .build())
                    .build())
                .build())
            .build());

    }
}
resources:
  test:
    type: aws:accessanalyzer:Analyzer
    properties:
      analyzerName: example
      type: ORGANIZATION_INTERNAL_ACCESS
      configuration:
        internalAccess:
          analysisRule:
            inclusions:
              - accountIds:
                  - '123456789012'
                resourceArns:
                  - arn:aws:s3:::my-example-bucket

Instead of filtering by resource type, this configuration uses accountIds and resourceArns to target specific resources. This provides the most precise control over what Access Analyzer monitors, useful when you need to track access to critical resources.

Beyond these examples

These snippets focus on specific analyzer features: account and organization-level analysis, unused access detection with exclusion rules, and internal access monitoring with resource filtering. They’re intentionally minimal rather than full access governance solutions.

The examples may reference pre-existing infrastructure such as AWS Organizations with access-analyzer.amazonaws.com service access (for organization analyzers), and specific account IDs and resource ARNs (for targeted analysis). They focus on configuring the analyzer rather than provisioning the surrounding governance infrastructure.

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

  • Tagging for cost allocation and organization
  • Archive rules for suppressing findings
  • Finding notifications and integrations
  • Cross-region analyzer deployment

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

Let's configure AWS Access Analyzer

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Analyzer Types & Scope
What are the different Access Analyzer types?
Six types are available: ACCOUNT, ACCOUNT_INTERNAL_ACCESS, ACCOUNT_UNUSED_ACCESS, ORGANIZATION, ORGANIZATION_INTERNAL_ACCESS, and ORGANIZATION_UNUSED_ACCESS. The default is ACCOUNT.
What's the difference between ACCOUNT and ORGANIZATION analyzers?
ACCOUNT analyzers scope to a single AWS account, while ORGANIZATION analyzers scope to your entire AWS Organization. Organization analyzers require AWS Organizations to be configured first.
When should I use UNUSED_ACCESS vs INTERNAL_ACCESS analyzers?
UNUSED_ACCESS analyzers identify unused permissions, while INTERNAL_ACCESS analyzers focus on access within your zone of trust. Both are available at ACCOUNT or ORGANIZATION scope.
Organization Setup
How do I set up an Organization analyzer?
Set type to ORGANIZATION and use dependsOn to ensure your aws.organizations.Organization resource is created first with awsServiceAccessPrincipals: ["access-analyzer.amazonaws.com"].
Why does my Organization analyzer fail to create?
Organization analyzers require AWS Organizations to grant access to the Access Analyzer service. Ensure awsServiceAccessPrincipals includes access-analyzer.amazonaws.com and use dependsOn to enforce creation order.
Configuration & Analysis Rules
How do I exclude specific accounts or resources from unused access analysis?
Use configuration.unusedAccess.analysisRule.exclusions with accountIds arrays or resourceTags to exclude resources from analysis.
How do I scope internal access analysis to specific resource types?
Use configuration.internalAccess.analysisRule.inclusions with a resourceTypes array containing resource types like AWS::S3::Bucket, AWS::RDS::DBSnapshot, or AWS::DynamoDB::Table.
Can I scope internal access analysis by account ID and resource ARN?
Yes, use configuration.internalAccess.analysisRule.inclusions with both accountIds and resourceArns arrays to target specific resources in specific accounts.
What's the difference between exclusions and inclusions in analysis rules?
Exclusions filter out resources from analysis (used with unusedAccess), while inclusions specify which resources to analyze (used with internalAccess).
Immutability & Lifecycle
What properties can't be changed after creating an analyzer?
The analyzerName, type, and configuration properties are immutable. Changing any of these requires replacing the analyzer.

Using a different cloud?

Explore security guides for other cloud providers: