The aws:route53/resolverRule:ResolverRule resource, part of the Pulumi AWS provider, defines Route 53 Resolver rules that control how DNS queries for specific domains are resolved: forwarded to custom DNS servers, blocked from forwarding, or handled recursively. This guide focuses on three capabilities: SYSTEM rules to block forwarding, FORWARD rules to on-premises DNS, and IPv6 target configuration.
Resolver rules work with outbound resolver endpoints to route queries between AWS and external DNS infrastructure. The examples are intentionally small. Combine them with your own VPC associations and resolver endpoints.
Override DNS resolution for specific subdomains
Organizations sometimes need to prevent Route 53 Resolver from forwarding queries for certain subdomains, keeping resolution within AWS’s default DNS behavior.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const sys = new aws.route53.ResolverRule("sys", {
domainName: "subdomain.example.com",
ruleType: "SYSTEM",
});
import pulumi
import pulumi_aws as aws
sys = aws.route53.ResolverRule("sys",
domain_name="subdomain.example.com",
rule_type="SYSTEM")
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/route53"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := route53.NewResolverRule(ctx, "sys", &route53.ResolverRuleArgs{
DomainName: pulumi.String("subdomain.example.com"),
RuleType: pulumi.String("SYSTEM"),
})
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 sys = new Aws.Route53.ResolverRule("sys", new()
{
DomainName = "subdomain.example.com",
RuleType = "SYSTEM",
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.route53.ResolverRule;
import com.pulumi.aws.route53.ResolverRuleArgs;
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 sys = new ResolverRule("sys", ResolverRuleArgs.builder()
.domainName("subdomain.example.com")
.ruleType("SYSTEM")
.build());
}
}
resources:
sys:
type: aws:route53:ResolverRule
properties:
domainName: subdomain.example.com
ruleType: SYSTEM
When ruleType is SYSTEM, Route 53 Resolver uses AWS’s default DNS resolution for the specified domainName instead of forwarding queries. This blocks forwarding rules that would otherwise apply to parent domains. SYSTEM rules require only domainName and ruleType; they don’t use resolverEndpointId or targetIps.
Forward DNS queries to on-premises resolvers
Hybrid cloud architectures often resolve private domain names by forwarding queries from AWS to corporate DNS servers.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const fwd = new aws.route53.ResolverRule("fwd", {
domainName: "example.com",
name: "example",
ruleType: "FORWARD",
resolverEndpointId: foo.id,
targetIps: [{
ip: "123.45.67.89",
}],
tags: {
Environment: "Prod",
},
});
import pulumi
import pulumi_aws as aws
fwd = aws.route53.ResolverRule("fwd",
domain_name="example.com",
name="example",
rule_type="FORWARD",
resolver_endpoint_id=foo["id"],
target_ips=[{
"ip": "123.45.67.89",
}],
tags={
"Environment": "Prod",
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/route53"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := route53.NewResolverRule(ctx, "fwd", &route53.ResolverRuleArgs{
DomainName: pulumi.String("example.com"),
Name: pulumi.String("example"),
RuleType: pulumi.String("FORWARD"),
ResolverEndpointId: pulumi.Any(foo.Id),
TargetIps: route53.ResolverRuleTargetIpArray{
&route53.ResolverRuleTargetIpArgs{
Ip: pulumi.String("123.45.67.89"),
},
},
Tags: pulumi.StringMap{
"Environment": pulumi.String("Prod"),
},
})
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 fwd = new Aws.Route53.ResolverRule("fwd", new()
{
DomainName = "example.com",
Name = "example",
RuleType = "FORWARD",
ResolverEndpointId = foo.Id,
TargetIps = new[]
{
new Aws.Route53.Inputs.ResolverRuleTargetIpArgs
{
Ip = "123.45.67.89",
},
},
Tags =
{
{ "Environment", "Prod" },
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.route53.ResolverRule;
import com.pulumi.aws.route53.ResolverRuleArgs;
import com.pulumi.aws.route53.inputs.ResolverRuleTargetIpArgs;
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 fwd = new ResolverRule("fwd", ResolverRuleArgs.builder()
.domainName("example.com")
.name("example")
.ruleType("FORWARD")
.resolverEndpointId(foo.id())
.targetIps(ResolverRuleTargetIpArgs.builder()
.ip("123.45.67.89")
.build())
.tags(Map.of("Environment", "Prod"))
.build());
}
}
resources:
fwd:
type: aws:route53:ResolverRule
properties:
domainName: example.com
name: example
ruleType: FORWARD
resolverEndpointId: ${foo.id}
targetIps:
- ip: 123.45.67.89
tags:
Environment: Prod
When ruleType is FORWARD, queries matching domainName are sent to the IP addresses in targetIps via the outbound resolver endpoint specified by resolverEndpointId. The resolver endpoint must exist in your VPC with network connectivity to the target DNS servers. Each targetIp entry specifies either an ip (IPv4) or ipv6 address.
Forward DNS queries to IPv6 resolvers
IPv6-enabled networks can forward queries to IPv6 addresses, supporting dual-stack or IPv6-only infrastructure.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
const fwd = new aws.route53.ResolverRule("fwd", {
domainName: "example.com",
name: "example",
ruleType: "FORWARD",
resolverEndpointId: foo.id,
targetIps: [{
ipv6: "2600:1f18:1686:2000:4e60:6e3e:258:da36",
}],
tags: {
Environment: "Prod",
},
});
import pulumi
import pulumi_aws as aws
fwd = aws.route53.ResolverRule("fwd",
domain_name="example.com",
name="example",
rule_type="FORWARD",
resolver_endpoint_id=foo["id"],
target_ips=[{
"ipv6": "2600:1f18:1686:2000:4e60:6e3e:258:da36",
}],
tags={
"Environment": "Prod",
})
package main
import (
"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/route53"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
_, err := route53.NewResolverRule(ctx, "fwd", &route53.ResolverRuleArgs{
DomainName: pulumi.String("example.com"),
Name: pulumi.String("example"),
RuleType: pulumi.String("FORWARD"),
ResolverEndpointId: pulumi.Any(foo.Id),
TargetIps: route53.ResolverRuleTargetIpArray{
&route53.ResolverRuleTargetIpArgs{
Ipv6: pulumi.String("2600:1f18:1686:2000:4e60:6e3e:258:da36"),
},
},
Tags: pulumi.StringMap{
"Environment": pulumi.String("Prod"),
},
})
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 fwd = new Aws.Route53.ResolverRule("fwd", new()
{
DomainName = "example.com",
Name = "example",
RuleType = "FORWARD",
ResolverEndpointId = foo.Id,
TargetIps = new[]
{
new Aws.Route53.Inputs.ResolverRuleTargetIpArgs
{
Ipv6 = "2600:1f18:1686:2000:4e60:6e3e:258:da36",
},
},
Tags =
{
{ "Environment", "Prod" },
},
});
});
package generated_program;
import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.route53.ResolverRule;
import com.pulumi.aws.route53.ResolverRuleArgs;
import com.pulumi.aws.route53.inputs.ResolverRuleTargetIpArgs;
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 fwd = new ResolverRule("fwd", ResolverRuleArgs.builder()
.domainName("example.com")
.name("example")
.ruleType("FORWARD")
.resolverEndpointId(foo.id())
.targetIps(ResolverRuleTargetIpArgs.builder()
.ipv6("2600:1f18:1686:2000:4e60:6e3e:258:da36")
.build())
.tags(Map.of("Environment", "Prod"))
.build());
}
}
resources:
fwd:
type: aws:route53:ResolverRule
properties:
domainName: example.com
name: example
ruleType: FORWARD
resolverEndpointId: ${foo.id}
targetIps:
- ipv6: 2600:1f18:1686:2000:4e60:6e3e:258:da36
tags:
Environment: Prod
This extends the forward rule pattern with IPv6 addressing. Instead of the ip field, use ipv6 in the targetIps configuration. The resolver endpoint and network path must support IPv6 connectivity to the target address.
Beyond these examples
These snippets focus on specific resolver rule features: SYSTEM rules for blocking forwarding and FORWARD rules with IPv4 and IPv6 targets. They’re intentionally minimal rather than complete DNS architectures.
The examples reference pre-existing infrastructure such as outbound resolver endpoints (resolverEndpointId) and network connectivity to target DNS servers. They focus on configuring the rule rather than provisioning resolver endpoints or VPC associations.
To keep things focused, common resolver patterns are omitted, including:
- RECURSIVE rule type for conditional forwarding
- Multiple target IPs for redundancy
- Rule association with VPCs (separate resource)
- Cross-account rule sharing
These omissions are intentional: the goal is to illustrate how each resolver rule type is wired, not provide drop-in DNS modules. See the Route 53 Resolver Rule resource reference for all available configuration options.
Let's configure AWS Route53 Resolver Rules
Get started with Pulumi Cloud, then follow our quick setup guide to deploy this infrastructure.
Try Pulumi Cloud for FREEFrequently Asked Questions
Rule Types & Configuration
FORWARD (forwards queries to specified IPs), SYSTEM (uses Route53 Resolver default behavior), and RECURSIVE (performs recursive DNS resolution).resolverEndpointId (outbound resolver endpoint) and targetIps (destination IP addresses for DNS queries). SYSTEM and RECURSIVE rules don’t need these properties.ruleType to SYSTEM and specify domainName. You don’t need resolverEndpointId or targetIps for SYSTEM rules.Immutability & Limitations
domainName and ruleType are immutable. Changing either requires replacing the resource.ruleType is immutable. You must delete the existing rule and create a new one with the desired type.IP Addressing & Endpoints
ipv6 field in the targetIps configuration block instead of the ip field.targetIps accepts multiple configuration blocks, each with either an ip (IPv4) or ipv6 field.Sharing & Cross-Account
shareStatus output property. Values are NOT_SHARED, SHARED_BY_ME (you shared it), or SHARED_WITH_ME (shared with you).ownerId output property contains the AWS account ID of the account that owns the rule when it’s shared.Using a different cloud?
Explore networking guides for other cloud providers: