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 resolvers, blocked from forwarding, or recursively resolved. This guide focuses on three capabilities: SYSTEM rules to block forwarding, FORWARD rules to route queries to on-premises or custom DNS servers, and IPv4 and IPv6 target configuration.
FORWARD rules require an outbound resolver endpoint to route queries through; SYSTEM rules operate independently. The examples are intentionally small. Combine them with your own resolver endpoints and VPC associations.
Override AWS default DNS resolution for a subdomain
Some organizations need to prevent Route 53 Resolver from forwarding queries for specific 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 you set ruleType to SYSTEM, Route 53 Resolver uses AWS’s default DNS resolution for the specified domainName instead of forwarding queries to custom resolvers. This is useful when you have a FORWARD rule for a parent domain but want a subdomain to resolve normally.
Forward DNS queries to on-premises resolvers
Hybrid cloud architectures often need to resolve private domain names that exist in on-premises data centers.
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 queries match the domainName, Route 53 Resolver forwards them through the outbound endpoint specified by resolverEndpointId to the DNS servers listed in targetIps. The ip property specifies the IPv4 address of each target resolver. You can list multiple target IPs for redundancy.
Forward DNS queries to IPv6 resolvers
Networks transitioning to IPv6 or operating dual-stack environments need to forward DNS queries to IPv6-addressed resolvers.
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 configuration works like the IPv4 forward rule, but uses the ipv6 property in targetIps to specify IPv6 addresses. Route 53 Resolver forwards matching queries through the outbound endpoint to the IPv6 resolvers.
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 full DNS architectures.
The examples may reference pre-existing infrastructure such as outbound resolver endpoints (for FORWARD rules). They focus on configuring the rule rather than provisioning endpoints or VPC associations.
To keep things focused, common resolver rule patterns are omitted, including:
- RECURSIVE rule type for conditional forwarding
- Multiple target IPs for redundancy
- Rule association with VPCs (aws.route53.ResolverRuleAssociation)
- Cross-account rule sharing (shareStatus)
These omissions are intentional: the goal is to illustrate how each resolver rule feature 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 (routes DNS queries to specified IP addresses), SYSTEM (uses AWS-managed routing), and RECURSIVE (performs standard DNS resolution).domainName, ruleType set to FORWARD, resolverEndpointId (outbound endpoint ID), and targetIps with at least one IP address.resolverEndpointId and targetIps should only be specified for FORWARD type rules. SYSTEM and RECURSIVE rules don’t use these properties.Immutability & Updates
domainName and ruleType are immutable. Changing either property forces replacement of the entire resolver rule.name property can be updated without replacing the resource.Forwarding & Target IPs
ipv6 field in the targetIps configuration block instead of the ip field.targetIps, with some using the ip field (IPv4) and others using the ipv6 field (IPv6).Using a different cloud?
Explore networking guides for other cloud providers: