The aws:cfg/rule:Rule resource, part of the Pulumi AWS provider, defines AWS Config rules that evaluate resource compliance against AWS managed rules, custom Lambda logic, or Guard policies. This guide focuses on three capabilities: AWS managed rule configuration, custom Lambda-based evaluation, and Guard policy language rules.
Config rules require an existing Configuration Recorder and IAM permissions. Custom rules also need Lambda functions or Guard policies. The examples are intentionally small. Combine them with your own recorder setup and compliance logic.
Evaluate resources with AWS managed rules
Most Config deployments start with AWS managed rules that check common compliance requirements without custom code.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const assumeRole = aws.iam.getPolicyDocument({
statements: [{
effect: "Allow",
principals: [{
type: "Service",
identifiers: ["config.amazonaws.com"],
}],
actions: ["sts:AssumeRole"],
}],
});
const rRole = new aws.iam.Role("r", {
name: "my-awsconfig-role",
assumeRolePolicy: assumeRole.then(assumeRole => assumeRole.json),
});
const foo = new aws.cfg.Recorder("foo", {
name: "example",
roleArn: rRole.arn,
});
const r = new aws.cfg.Rule("r", {
name: "example",
source: {
owner: "AWS",
sourceIdentifier: "S3_BUCKET_VERSIONING_ENABLED",
},
}, {
dependsOn: [foo],
});
const p = aws.iam.getPolicyDocument({
statements: [{
effect: "Allow",
actions: ["config:Put*"],
resources: ["*"],
}],
});
const pRolePolicy = new aws.iam.RolePolicy("p", {
name: "my-awsconfig-policy",
role: rRole.id,
policy: p.then(p => p.json),
});
import pulumi
import pulumi_aws as aws
assume_role = aws.iam.get_policy_document(statements=[{
"effect": "Allow",
"principals": [{
"type": "Service",
"identifiers": ["config.amazonaws.com"],
}],
"actions": ["sts:AssumeRole"],
}])
r_role = aws.iam.Role("r",
name="my-awsconfig-role",
assume_role_policy=assume_role.json)
foo = aws.cfg.Recorder("foo",
name="example",
role_arn=r_role.arn)
r = aws.cfg.Rule("r",
name="example",
source={
"owner": "AWS",
"source_identifier": "S3_BUCKET_VERSIONING_ENABLED",
},
opts = pulumi.ResourceOptions(depends_on=[foo]))
p = aws.iam.get_policy_document(statements=[{
"effect": "Allow",
"actions": ["config:Put*"],
"resources": ["*"],
}])
p_role_policy = aws.iam.RolePolicy("p",
name="my-awsconfig-policy",
role=r_role.id,
policy=p.json)
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cfg"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
assumeRole, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
Statements: []iam.GetPolicyDocumentStatement{
{
Effect: pulumi.StringRef("Allow"),
Principals: []iam.GetPolicyDocumentStatementPrincipal{
{
Type: "Service",
Identifiers: []string{
"config.amazonaws.com",
},
},
},
Actions: []string{
"sts:AssumeRole",
},
},
},
}, nil)
if err != nil {
return err
}
rRole, err := iam.NewRole(ctx, "r", &iam.RoleArgs{
Name: pulumi.String("my-awsconfig-role"),
AssumeRolePolicy: pulumi.String(assumeRole.Json),
})
if err != nil {
return err
}
foo, err := cfg.NewRecorder(ctx, "foo", &cfg.RecorderArgs{
Name: pulumi.String("example"),
RoleArn: rRole.Arn,
})
if err != nil {
return err
}
_, err = cfg.NewRule(ctx, "r", &cfg.RuleArgs{
Name: pulumi.String("example"),
Source: &cfg.RuleSourceArgs{
Owner: pulumi.String("AWS"),
SourceIdentifier: pulumi.String("S3_BUCKET_VERSIONING_ENABLED"),
},
}, pulumi.DependsOn([]pulumi.Resource{
foo,
}))
if err != nil {
return err
}
p, err := iam.GetPolicyDocument(ctx, &iam.GetPolicyDocumentArgs{
Statements: []iam.GetPolicyDocumentStatement{
{
Effect: pulumi.StringRef("Allow"),
Actions: []string{
"config:Put*",
},
Resources: []string{
"*",
},
},
},
}, nil)
if err != nil {
return err
}
_, err = iam.NewRolePolicy(ctx, "p", &iam.RolePolicyArgs{
Name: pulumi.String("my-awsconfig-policy"),
Role: rRole.ID(),
Policy: pulumi.String(p.Json),
})
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 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[]
{
"config.amazonaws.com",
},
},
},
Actions = new[]
{
"sts:AssumeRole",
},
},
},
});
var rRole = new Aws.Iam.Role("r", new()
{
Name = "my-awsconfig-role",
AssumeRolePolicy = assumeRole.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
});
var foo = new Aws.Cfg.Recorder("foo", new()
{
Name = "example",
RoleArn = rRole.Arn,
});
var r = new Aws.Cfg.Rule("r", new()
{
Name = "example",
Source = new Aws.Cfg.Inputs.RuleSourceArgs
{
Owner = "AWS",
SourceIdentifier = "S3_BUCKET_VERSIONING_ENABLED",
},
}, new CustomResourceOptions
{
DependsOn =
{
foo,
},
});
var p = Aws.Iam.GetPolicyDocument.Invoke(new()
{
Statements = new[]
{
new Aws.Iam.Inputs.GetPolicyDocumentStatementInputArgs
{
Effect = "Allow",
Actions = new[]
{
"config:Put*",
},
Resources = new[]
{
"*",
},
},
},
});
var pRolePolicy = new Aws.Iam.RolePolicy("p", new()
{
Name = "my-awsconfig-policy",
Role = rRole.Id,
Policy = p.Apply(getPolicyDocumentResult => getPolicyDocumentResult.Json),
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
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.cfg.Recorder;
import com.pulumi.aws.cfg.RecorderArgs;
import com.pulumi.aws.cfg.Rule;
import com.pulumi.aws.cfg.RuleArgs;
import com.pulumi.aws.cfg.inputs.RuleSourceArgs;
import com.pulumi.aws.iam.RolePolicy;
import com.pulumi.aws.iam.RolePolicyArgs;
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) {
final var assumeRole = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
.statements(GetPolicyDocumentStatementArgs.builder()
.effect("Allow")
.principals(GetPolicyDocumentStatementPrincipalArgs.builder()
.type("Service")
.identifiers("config.amazonaws.com")
.build())
.actions("sts:AssumeRole")
.build())
.build());
var rRole = new Role("rRole", RoleArgs.builder()
.name("my-awsconfig-role")
.assumeRolePolicy(assumeRole.json())
.build());
var foo = new Recorder("foo", RecorderArgs.builder()
.name("example")
.roleArn(rRole.arn())
.build());
var r = new Rule("r", RuleArgs.builder()
.name("example")
.source(RuleSourceArgs.builder()
.owner("AWS")
.sourceIdentifier("S3_BUCKET_VERSIONING_ENABLED")
.build())
.build(), CustomResourceOptions.builder()
.dependsOn(foo)
.build());
final var p = IamFunctions.getPolicyDocument(GetPolicyDocumentArgs.builder()
.statements(GetPolicyDocumentStatementArgs.builder()
.effect("Allow")
.actions("config:Put*")
.resources("*")
.build())
.build());
var pRolePolicy = new RolePolicy("pRolePolicy", RolePolicyArgs.builder()
.name("my-awsconfig-policy")
.role(rRole.id())
.policy(p.json())
.build());
}
}
resources:
r:
type: aws:cfg:Rule
properties:
name: example
source:
owner: AWS
sourceIdentifier: S3_BUCKET_VERSIONING_ENABLED
options:
dependsOn:
- ${foo}
foo:
type: aws:cfg:Recorder
properties:
name: example
roleArn: ${rRole.arn}
rRole:
type: aws:iam:Role
name: r
properties:
name: my-awsconfig-role
assumeRolePolicy: ${assumeRole.json}
pRolePolicy:
type: aws:iam:RolePolicy
name: p
properties:
name: my-awsconfig-policy
role: ${rRole.id}
policy: ${p.json}
variables:
assumeRole:
fn::invoke:
function: aws:iam:getPolicyDocument
arguments:
statements:
- effect: Allow
principals:
- type: Service
identifiers:
- config.amazonaws.com
actions:
- sts:AssumeRole
p:
fn::invoke:
function: aws:iam:getPolicyDocument
arguments:
statements:
- effect: Allow
actions:
- config:Put*
resources:
- '*'
The source property defines the rule owner and identifier. Setting owner to “AWS” and sourceIdentifier to a managed rule name (like “S3_BUCKET_VERSIONING_ENABLED”) tells Config to use AWS-provided evaluation logic. The dependsOn relationship ensures the Configuration Recorder exists before creating the rule, avoiding race conditions during deployment.
Run custom compliance logic with Lambda functions
When AWS managed rules don’t cover your specific requirements, you can write custom evaluation logic in Lambda.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.cfg.Recorder("example", {});
const exampleFunction = new aws.lambda.Function("example", {});
const examplePermission = new aws.lambda.Permission("example", {
action: "lambda:InvokeFunction",
"function": exampleFunction.arn,
principal: "config.amazonaws.com",
statementId: "AllowExecutionFromConfig",
});
const exampleRule = new aws.cfg.Rule("example", {source: {
owner: "CUSTOM_LAMBDA",
sourceIdentifier: exampleFunction.arn,
}}, {
dependsOn: [
example,
examplePermission,
],
});
import pulumi
import pulumi_aws as aws
example = aws.cfg.Recorder("example")
example_function = aws.lambda_.Function("example")
example_permission = aws.lambda_.Permission("example",
action="lambda:InvokeFunction",
function=example_function.arn,
principal="config.amazonaws.com",
statement_id="AllowExecutionFromConfig")
example_rule = aws.cfg.Rule("example", source={
"owner": "CUSTOM_LAMBDA",
"source_identifier": example_function.arn,
},
opts = pulumi.ResourceOptions(depends_on=[
example,
example_permission,
]))
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cfg"
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/lambda"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
example, err := cfg.NewRecorder(ctx, "example", nil)
if err != nil {
return err
}
exampleFunction, err := lambda.NewFunction(ctx, "example", nil)
if err != nil {
return err
}
examplePermission, err := lambda.NewPermission(ctx, "example", &lambda.PermissionArgs{
Action: pulumi.String("lambda:InvokeFunction"),
Function: exampleFunction.Arn,
Principal: pulumi.String("config.amazonaws.com"),
StatementId: pulumi.String("AllowExecutionFromConfig"),
})
if err != nil {
return err
}
_, err = cfg.NewRule(ctx, "example", &cfg.RuleArgs{
Source: &cfg.RuleSourceArgs{
Owner: pulumi.String("CUSTOM_LAMBDA"),
SourceIdentifier: exampleFunction.Arn,
},
}, pulumi.DependsOn([]pulumi.Resource{
example,
examplePermission,
}))
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.Cfg.Recorder("example");
var exampleFunction = new Aws.Lambda.Function("example");
var examplePermission = new Aws.Lambda.Permission("example", new()
{
Action = "lambda:InvokeFunction",
Function = exampleFunction.Arn,
Principal = "config.amazonaws.com",
StatementId = "AllowExecutionFromConfig",
});
var exampleRule = new Aws.Cfg.Rule("example", new()
{
Source = new Aws.Cfg.Inputs.RuleSourceArgs
{
Owner = "CUSTOM_LAMBDA",
SourceIdentifier = exampleFunction.Arn,
},
}, new CustomResourceOptions
{
DependsOn =
{
example,
examplePermission,
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.cfg.Recorder;
import com.pulumi.aws.lambda.Function;
import com.pulumi.aws.lambda.Permission;
import com.pulumi.aws.lambda.PermissionArgs;
import com.pulumi.aws.cfg.Rule;
import com.pulumi.aws.cfg.RuleArgs;
import com.pulumi.aws.cfg.inputs.RuleSourceArgs;
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 Recorder("example");
var exampleFunction = new Function("exampleFunction");
var examplePermission = new Permission("examplePermission", PermissionArgs.builder()
.action("lambda:InvokeFunction")
.function(exampleFunction.arn())
.principal("config.amazonaws.com")
.statementId("AllowExecutionFromConfig")
.build());
var exampleRule = new Rule("exampleRule", RuleArgs.builder()
.source(RuleSourceArgs.builder()
.owner("CUSTOM_LAMBDA")
.sourceIdentifier(exampleFunction.arn())
.build())
.build(), CustomResourceOptions.builder()
.dependsOn(
example,
examplePermission)
.build());
}
}
resources:
example:
type: aws:cfg:Recorder
exampleFunction:
type: aws:lambda:Function
name: example
examplePermission:
type: aws:lambda:Permission
name: example
properties:
action: lambda:InvokeFunction
function: ${exampleFunction.arn}
principal: config.amazonaws.com
statementId: AllowExecutionFromConfig
exampleRule:
type: aws:cfg:Rule
name: example
properties:
source:
owner: CUSTOM_LAMBDA
sourceIdentifier: ${exampleFunction.arn}
options:
dependsOn:
- ${example}
- ${examplePermission}
Setting owner to “CUSTOM_LAMBDA” and sourceIdentifier to your Lambda function ARN tells Config to invoke your function for evaluations. The lambda.Permission resource grants config.amazonaws.com permission to invoke the function. The dependsOn array ensures both the recorder and Lambda permissions exist before creating the rule.
Define compliance rules with Guard policy language
Guard policies let you write compliance rules declaratively without managing Lambda functions.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const example = new aws.cfg.Rule("example", {
name: "example",
source: {
owner: "CUSTOM_POLICY",
sourceDetails: [{
messageType: "ConfigurationItemChangeNotification",
}],
customPolicyDetails: {
policyRuntime: "guard-2.x.x",
policyText: `\\t rule tableisactive when
\\t\\t resourceType == \\"AWS::DynamoDB::Table\\" {
\\t\\t configuration.tableStatus == ['ACTIVE']
\\t }
\\t
\\t rule checkcompliance when
\\t\\t resourceType == \\"AWS::DynamoDB::Table\\"
\\t\\t tableisactive {
\\t\\t\\t supplementaryConfiguration.ContinuousBackupsDescription.pointInTimeRecoveryDescription.pointInTimeRecoveryStatus == \\"ENABLED\\"
\\t }
`,
},
},
});
import pulumi
import pulumi_aws as aws
example = aws.cfg.Rule("example",
name="example",
source={
"owner": "CUSTOM_POLICY",
"source_details": [{
"message_type": "ConfigurationItemChangeNotification",
}],
"custom_policy_details": {
"policy_runtime": "guard-2.x.x",
"policy_text": """\t rule tableisactive when
\t\t resourceType == \"AWS::DynamoDB::Table\" {
\t\t configuration.tableStatus == ['ACTIVE']
\t }
\t
\t rule checkcompliance when
\t\t resourceType == \"AWS::DynamoDB::Table\"
\t\t tableisactive {
\t\t\t supplementaryConfiguration.ContinuousBackupsDescription.pointInTimeRecoveryDescription.pointInTimeRecoveryStatus == \"ENABLED\"
\t }
""",
},
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/cfg"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := cfg.NewRule(ctx, "example", &cfg.RuleArgs{
Name: pulumi.String("example"),
Source: &cfg.RuleSourceArgs{
Owner: pulumi.String("CUSTOM_POLICY"),
SourceDetails: cfg.RuleSourceSourceDetailArray{
&cfg.RuleSourceSourceDetailArgs{
MessageType: pulumi.String("ConfigurationItemChangeNotification"),
},
},
CustomPolicyDetails: &cfg.RuleSourceCustomPolicyDetailsArgs{
PolicyRuntime: pulumi.String("guard-2.x.x"),
PolicyText: pulumi.String(`\t rule tableisactive when
\t\t resourceType == \"AWS::DynamoDB::Table\" {
\t\t configuration.tableStatus == ['ACTIVE']
\t }
\t
\t rule checkcompliance when
\t\t resourceType == \"AWS::DynamoDB::Table\"
\t\t tableisactive {
\t\t\t supplementaryConfiguration.ContinuousBackupsDescription.pointInTimeRecoveryDescription.pointInTimeRecoveryStatus == \"ENABLED\"
\t }
`),
},
},
})
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.Cfg.Rule("example", new()
{
Name = "example",
Source = new Aws.Cfg.Inputs.RuleSourceArgs
{
Owner = "CUSTOM_POLICY",
SourceDetails = new[]
{
new Aws.Cfg.Inputs.RuleSourceSourceDetailArgs
{
MessageType = "ConfigurationItemChangeNotification",
},
},
CustomPolicyDetails = new Aws.Cfg.Inputs.RuleSourceCustomPolicyDetailsArgs
{
PolicyRuntime = "guard-2.x.x",
PolicyText = @"\t rule tableisactive when
\t\t resourceType == \""AWS::DynamoDB::Table\"" {
\t\t configuration.tableStatus == ['ACTIVE']
\t }
\t
\t rule checkcompliance when
\t\t resourceType == \""AWS::DynamoDB::Table\""
\t\t tableisactive {
\t\t\t supplementaryConfiguration.ContinuousBackupsDescription.pointInTimeRecoveryDescription.pointInTimeRecoveryStatus == \""ENABLED\""
\t }
",
},
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.cfg.Rule;
import com.pulumi.aws.cfg.RuleArgs;
import com.pulumi.aws.cfg.inputs.RuleSourceArgs;
import com.pulumi.aws.cfg.inputs.RuleSourceCustomPolicyDetailsArgs;
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 Rule("example", RuleArgs.builder()
.name("example")
.source(RuleSourceArgs.builder()
.owner("CUSTOM_POLICY")
.sourceDetails(RuleSourceSourceDetailArgs.builder()
.messageType("ConfigurationItemChangeNotification")
.build())
.customPolicyDetails(RuleSourceCustomPolicyDetailsArgs.builder()
.policyRuntime("guard-2.x.x")
.policyText("""
\t rule tableisactive when
\t\t resourceType == \"AWS::DynamoDB::Table\" {
\t\t configuration.tableStatus == ['ACTIVE']
\t }
\t
\t rule checkcompliance when
\t\t resourceType == \"AWS::DynamoDB::Table\"
\t\t tableisactive {
\t\t\t supplementaryConfiguration.ContinuousBackupsDescription.pointInTimeRecoveryDescription.pointInTimeRecoveryStatus == \"ENABLED\"
\t }
""")
.build())
.build())
.build());
}
}
resources:
example:
type: aws:cfg:Rule
properties:
name: example
source:
owner: CUSTOM_POLICY
sourceDetails:
- messageType: ConfigurationItemChangeNotification
customPolicyDetails:
policyRuntime: guard-2.x.x
policyText: "\\t rule tableisactive when\n\\t\\t resourceType == \\\"AWS::DynamoDB::Table\\\" {\n\\t\\t configuration.tableStatus == ['ACTIVE']\n\\t }\n\\t \n\\t rule checkcompliance when\n\\t\\t resourceType == \\\"AWS::DynamoDB::Table\\\"\n\\t\\t tableisactive {\n\\t\\t\\t supplementaryConfiguration.ContinuousBackupsDescription.pointInTimeRecoveryDescription.pointInTimeRecoveryStatus == \\\"ENABLED\\\"\n\\t }\n"
The CUSTOM_POLICY owner type uses Guard policy language for evaluation. The customPolicyDetails property specifies the policy runtime (guard-2.x.x) and the policy text itself. The sourceDetails property defines when Config triggers evaluation, in this case on configuration changes. Guard policies are useful for straightforward resource property checks that don’t require complex logic.
Beyond these examples
These snippets focus on specific Config rule features: AWS managed rules and custom Lambda evaluation, and Guard policy language for declarative checks. They’re intentionally minimal rather than full compliance frameworks.
The examples rely on pre-existing infrastructure such as Configuration Recorder (required for all rules), IAM roles with config:Put* permissions, and Lambda functions for custom rule logic. They focus on rule configuration rather than provisioning the surrounding infrastructure.
To keep things focused, common rule patterns are omitted, including:
- Resource scope filtering (scope property)
- Input parameters for rule configuration (inputParameters)
- Evaluation frequency controls (maximumExecutionFrequency)
- Evaluation modes for proactive vs detective checks
These omissions are intentional: the goal is to illustrate how each rule type is wired, not provide drop-in compliance modules. See the Config Rule resource reference for all available configuration options.
Let's configure AWS Config Rules
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Setup & Dependencies
dependsOn to ensure the Recorder is created before the Rule to avoid race conditions.aws.cfg.Recorder resource. For custom Lambda rules, you also need the Lambda function and an aws.lambda.Permission allowing config.amazonaws.com to invoke it.Rule Types & Configuration
owner: "AWS"), custom Lambda rules (owner: "CUSTOM_LAMBDA"), and custom policy rules (owner: "CUSTOM_POLICY").source.owner to "AWS" and source.sourceIdentifier to the managed rule name, such as "S3_BUCKET_VERSIONING_ENABLED". Find available rules in the AWS Config Developer Guide.source.owner to "CUSTOM_LAMBDA" and source.sourceIdentifier to your Lambda function’s ARN. You must also create an aws.lambda.Permission with principal: "config.amazonaws.com" and action: "lambda:InvokeFunction".source.owner to "CUSTOM_POLICY" and provide customPolicyDetails with policyRuntime (e.g., "guard-2.x.x") and policyText containing your Guard policy.sourceIdentifier is the rule name (like "S3_BUCKET_VERSIONING_ENABLED"). For custom Lambda rules, it’s the Lambda function ARN.Configuration & Scope
inputParameters property with a JSON string that will be passed to your Lambda function.scope property to define which resources can trigger evaluation. Without it, the rule evaluates based on the source configuration.evaluationModes property specifies the modes in which the Config rule can be evaluated. This is a required property.Limitations & Permissions
name property is immutable. Changing it requires destroying and recreating the rule.aws.lambda.Permission resource with principal: "config.amazonaws.com" and include it in your rule’s dependsOn.Using a different cloud?
Explore monitoring guides for other cloud providers: