Configure AWS Network Manager Connect Peers

The aws:networkmanager/connectPeer:ConnectPeer resource, part of the Pulumi AWS provider, establishes BGP peering sessions between your AWS Cloud WAN core network and external networks through Connect attachments. This guide focuses on two capabilities: GRE-based BGP peering and tunnel-less direct connectivity.

Connect peers depend on an existing Cloud WAN core network, a VPC attachment serving as transport, and a Connect attachment that defines the encapsulation protocol. The examples are intentionally small. Combine them with your own core network topology and routing policies.

Establish BGP peering with GRE encapsulation

Most Connect peer deployments use GRE tunnels to establish BGP sessions between your core network and on-premises routers, providing encrypted connectivity for dynamic routing.

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

const example = new aws.networkmanager.VpcAttachment("example", {
    subnetArns: exampleAwsSubnet.map(__item => __item.arn),
    coreNetworkId: exampleAwsccNetworkmanagerCoreNetwork.id,
    vpcArn: exampleAwsVpc.arn,
});
const exampleConnectAttachment = new aws.networkmanager.ConnectAttachment("example", {
    coreNetworkId: exampleAwsccNetworkmanagerCoreNetwork.id,
    transportAttachmentId: example.id,
    edgeLocation: example.edgeLocation,
    options: {
        protocol: "GRE",
    },
});
const exampleConnectPeer = new aws.networkmanager.ConnectPeer("example", {
    connectAttachmentId: exampleConnectAttachment.id,
    peerAddress: "127.0.0.1",
    bgpOptions: {
        peerAsn: "65000",
    },
    insideCidrBlocks: ["172.16.0.0/16"],
});
import pulumi
import pulumi_aws as aws

example = aws.networkmanager.VpcAttachment("example",
    subnet_arns=[__item["arn"] for __item in example_aws_subnet],
    core_network_id=example_awscc_networkmanager_core_network["id"],
    vpc_arn=example_aws_vpc["arn"])
example_connect_attachment = aws.networkmanager.ConnectAttachment("example",
    core_network_id=example_awscc_networkmanager_core_network["id"],
    transport_attachment_id=example.id,
    edge_location=example.edge_location,
    options={
        "protocol": "GRE",
    })
example_connect_peer = aws.networkmanager.ConnectPeer("example",
    connect_attachment_id=example_connect_attachment.id,
    peer_address="127.0.0.1",
    bgp_options={
        "peer_asn": "65000",
    },
    inside_cidr_blocks=["172.16.0.0/16"])
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/networkmanager"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
var splat0 []interface{}
for _, val0 := range exampleAwsSubnet {
splat0 = append(splat0, val0.Arn)
}
example, err := networkmanager.NewVpcAttachment(ctx, "example", &networkmanager.VpcAttachmentArgs{
SubnetArns: toPulumiArray(splat0),
CoreNetworkId: pulumi.Any(exampleAwsccNetworkmanagerCoreNetwork.Id),
VpcArn: pulumi.Any(exampleAwsVpc.Arn),
})
if err != nil {
return err
}
exampleConnectAttachment, err := networkmanager.NewConnectAttachment(ctx, "example", &networkmanager.ConnectAttachmentArgs{
CoreNetworkId: pulumi.Any(exampleAwsccNetworkmanagerCoreNetwork.Id),
TransportAttachmentId: example.ID(),
EdgeLocation: example.EdgeLocation,
Options: &networkmanager.ConnectAttachmentOptionsArgs{
Protocol: pulumi.String("GRE"),
},
})
if err != nil {
return err
}
_, err = networkmanager.NewConnectPeer(ctx, "example", &networkmanager.ConnectPeerArgs{
ConnectAttachmentId: exampleConnectAttachment.ID(),
PeerAddress: pulumi.String("127.0.0.1"),
BgpOptions: &networkmanager.ConnectPeerBgpOptionsArgs{
PeerAsn: pulumi.String("65000"),
},
InsideCidrBlocks: pulumi.StringArray{
pulumi.String("172.16.0.0/16"),
},
})
if err != nil {
return err
}
return nil
})
}
func toPulumiArray(arr []) pulumi.Array {
var pulumiArr pulumi.Array
for _, v := range arr {
pulumiArr = append(pulumiArr, pulumi.(v))
}
return pulumiArr
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.NetworkManager.VpcAttachment("example", new()
    {
        SubnetArns = exampleAwsSubnet.Select(__item => __item.Arn).ToList(),
        CoreNetworkId = exampleAwsccNetworkmanagerCoreNetwork.Id,
        VpcArn = exampleAwsVpc.Arn,
    });

    var exampleConnectAttachment = new Aws.NetworkManager.ConnectAttachment("example", new()
    {
        CoreNetworkId = exampleAwsccNetworkmanagerCoreNetwork.Id,
        TransportAttachmentId = example.Id,
        EdgeLocation = example.EdgeLocation,
        Options = new Aws.NetworkManager.Inputs.ConnectAttachmentOptionsArgs
        {
            Protocol = "GRE",
        },
    });

    var exampleConnectPeer = new Aws.NetworkManager.ConnectPeer("example", new()
    {
        ConnectAttachmentId = exampleConnectAttachment.Id,
        PeerAddress = "127.0.0.1",
        BgpOptions = new Aws.NetworkManager.Inputs.ConnectPeerBgpOptionsArgs
        {
            PeerAsn = "65000",
        },
        InsideCidrBlocks = new[]
        {
            "172.16.0.0/16",
        },
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.networkmanager.VpcAttachment;
import com.pulumi.aws.networkmanager.VpcAttachmentArgs;
import com.pulumi.aws.networkmanager.ConnectAttachment;
import com.pulumi.aws.networkmanager.ConnectAttachmentArgs;
import com.pulumi.aws.networkmanager.inputs.ConnectAttachmentOptionsArgs;
import com.pulumi.aws.networkmanager.ConnectPeer;
import com.pulumi.aws.networkmanager.ConnectPeerArgs;
import com.pulumi.aws.networkmanager.inputs.ConnectPeerBgpOptionsArgs;
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 VpcAttachment("example", VpcAttachmentArgs.builder()
            .subnetArns(exampleAwsSubnet.stream().map(element -> element.arn()).collect(toList()))
            .coreNetworkId(exampleAwsccNetworkmanagerCoreNetwork.id())
            .vpcArn(exampleAwsVpc.arn())
            .build());

        var exampleConnectAttachment = new ConnectAttachment("exampleConnectAttachment", ConnectAttachmentArgs.builder()
            .coreNetworkId(exampleAwsccNetworkmanagerCoreNetwork.id())
            .transportAttachmentId(example.id())
            .edgeLocation(example.edgeLocation())
            .options(ConnectAttachmentOptionsArgs.builder()
                .protocol("GRE")
                .build())
            .build());

        var exampleConnectPeer = new ConnectPeer("exampleConnectPeer", ConnectPeerArgs.builder()
            .connectAttachmentId(exampleConnectAttachment.id())
            .peerAddress("127.0.0.1")
            .bgpOptions(ConnectPeerBgpOptionsArgs.builder()
                .peerAsn("65000")
                .build())
            .insideCidrBlocks("172.16.0.0/16")
            .build());

    }
}

The Connect peer establishes a BGP session with your on-premises router at the specified peerAddress. The bgpOptions block configures the peer’s ASN for BGP negotiation. The insideCidrBlocks property defines the IP ranges used inside the GRE tunnel for BGP peering traffic. The Connect attachment’s protocol must be set to “GRE” when using insideCidrBlocks.

Connect directly without tunnel encapsulation

Some deployments bypass GRE tunneling when the underlying transport already provides isolation, reducing overhead with direct IP connectivity.

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

const example = new aws.networkmanager.VpcAttachment("example", {
    subnetArns: exampleAwsSubnet.map(__item => __item.arn),
    coreNetworkId: exampleAwsccNetworkmanagerCoreNetwork.id,
    vpcArn: exampleAwsVpc.arn,
});
const exampleConnectAttachment = new aws.networkmanager.ConnectAttachment("example", {
    coreNetworkId: exampleAwsccNetworkmanagerCoreNetwork.id,
    transportAttachmentId: example.id,
    edgeLocation: example.edgeLocation,
    options: {
        protocol: "NO_ENCAP",
    },
});
const exampleConnectPeer = new aws.networkmanager.ConnectPeer("example", {
    connectAttachmentId: exampleConnectAttachment.id,
    peerAddress: "127.0.0.1",
    bgpOptions: {
        peerAsn: "65000",
    },
    subnetArn: example2.arn,
});
import pulumi
import pulumi_aws as aws

example = aws.networkmanager.VpcAttachment("example",
    subnet_arns=[__item["arn"] for __item in example_aws_subnet],
    core_network_id=example_awscc_networkmanager_core_network["id"],
    vpc_arn=example_aws_vpc["arn"])
example_connect_attachment = aws.networkmanager.ConnectAttachment("example",
    core_network_id=example_awscc_networkmanager_core_network["id"],
    transport_attachment_id=example.id,
    edge_location=example.edge_location,
    options={
        "protocol": "NO_ENCAP",
    })
example_connect_peer = aws.networkmanager.ConnectPeer("example",
    connect_attachment_id=example_connect_attachment.id,
    peer_address="127.0.0.1",
    bgp_options={
        "peer_asn": "65000",
    },
    subnet_arn=example2["arn"])
package main

import (
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/networkmanager"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
var splat0 []interface{}
for _, val0 := range exampleAwsSubnet {
splat0 = append(splat0, val0.Arn)
}
example, err := networkmanager.NewVpcAttachment(ctx, "example", &networkmanager.VpcAttachmentArgs{
SubnetArns: toPulumiArray(splat0),
CoreNetworkId: pulumi.Any(exampleAwsccNetworkmanagerCoreNetwork.Id),
VpcArn: pulumi.Any(exampleAwsVpc.Arn),
})
if err != nil {
return err
}
exampleConnectAttachment, err := networkmanager.NewConnectAttachment(ctx, "example", &networkmanager.ConnectAttachmentArgs{
CoreNetworkId: pulumi.Any(exampleAwsccNetworkmanagerCoreNetwork.Id),
TransportAttachmentId: example.ID(),
EdgeLocation: example.EdgeLocation,
Options: &networkmanager.ConnectAttachmentOptionsArgs{
Protocol: pulumi.String("NO_ENCAP"),
},
})
if err != nil {
return err
}
_, err = networkmanager.NewConnectPeer(ctx, "example", &networkmanager.ConnectPeerArgs{
ConnectAttachmentId: exampleConnectAttachment.ID(),
PeerAddress: pulumi.String("127.0.0.1"),
BgpOptions: &networkmanager.ConnectPeerBgpOptionsArgs{
PeerAsn: pulumi.String("65000"),
},
SubnetArn: pulumi.Any(example2.Arn),
})
if err != nil {
return err
}
return nil
})
}
func toPulumiArray(arr []) pulumi.Array {
var pulumiArr pulumi.Array
for _, v := range arr {
pulumiArr = append(pulumiArr, pulumi.(v))
}
return pulumiArr
}
using System.Collections.Generic;
using System.Linq;
using Pulumi;
using Aws = Pulumi.Aws;

return await Deployment.RunAsync(() => 
{
    var example = new Aws.NetworkManager.VpcAttachment("example", new()
    {
        SubnetArns = exampleAwsSubnet.Select(__item => __item.Arn).ToList(),
        CoreNetworkId = exampleAwsccNetworkmanagerCoreNetwork.Id,
        VpcArn = exampleAwsVpc.Arn,
    });

    var exampleConnectAttachment = new Aws.NetworkManager.ConnectAttachment("example", new()
    {
        CoreNetworkId = exampleAwsccNetworkmanagerCoreNetwork.Id,
        TransportAttachmentId = example.Id,
        EdgeLocation = example.EdgeLocation,
        Options = new Aws.NetworkManager.Inputs.ConnectAttachmentOptionsArgs
        {
            Protocol = "NO_ENCAP",
        },
    });

    var exampleConnectPeer = new Aws.NetworkManager.ConnectPeer("example", new()
    {
        ConnectAttachmentId = exampleConnectAttachment.Id,
        PeerAddress = "127.0.0.1",
        BgpOptions = new Aws.NetworkManager.Inputs.ConnectPeerBgpOptionsArgs
        {
            PeerAsn = "65000",
        },
        SubnetArn = example2.Arn,
    });

});
package generated_program;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.core.Output;
import com.pulumi.aws.networkmanager.VpcAttachment;
import com.pulumi.aws.networkmanager.VpcAttachmentArgs;
import com.pulumi.aws.networkmanager.ConnectAttachment;
import com.pulumi.aws.networkmanager.ConnectAttachmentArgs;
import com.pulumi.aws.networkmanager.inputs.ConnectAttachmentOptionsArgs;
import com.pulumi.aws.networkmanager.ConnectPeer;
import com.pulumi.aws.networkmanager.ConnectPeerArgs;
import com.pulumi.aws.networkmanager.inputs.ConnectPeerBgpOptionsArgs;
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 VpcAttachment("example", VpcAttachmentArgs.builder()
            .subnetArns(exampleAwsSubnet.stream().map(element -> element.arn()).collect(toList()))
            .coreNetworkId(exampleAwsccNetworkmanagerCoreNetwork.id())
            .vpcArn(exampleAwsVpc.arn())
            .build());

        var exampleConnectAttachment = new ConnectAttachment("exampleConnectAttachment", ConnectAttachmentArgs.builder()
            .coreNetworkId(exampleAwsccNetworkmanagerCoreNetwork.id())
            .transportAttachmentId(example.id())
            .edgeLocation(example.edgeLocation())
            .options(ConnectAttachmentOptionsArgs.builder()
                .protocol("NO_ENCAP")
                .build())
            .build());

        var exampleConnectPeer = new ConnectPeer("exampleConnectPeer", ConnectPeerArgs.builder()
            .connectAttachmentId(exampleConnectAttachment.id())
            .peerAddress("127.0.0.1")
            .bgpOptions(ConnectPeerBgpOptionsArgs.builder()
                .peerAsn("65000")
                .build())
            .subnetArn(example2.arn())
            .build());

    }
}

When the Connect attachment uses “NO_ENCAP” protocol, the Connect peer establishes BGP sessions without GRE encapsulation. Instead of insideCidrBlocks, you specify a subnetArn where the peer terminates. This reduces packet overhead but requires the transport layer to provide network isolation.

Beyond these examples

These snippets focus on specific Connect peer features: BGP session establishment and GRE and tunnel-less connectivity. They’re intentionally minimal rather than full network topologies.

The examples rely on pre-existing infrastructure such as an AWS Cloud WAN core network and VPC with subnets for attachment. They focus on configuring the BGP peer rather than provisioning the entire Cloud WAN environment.

To keep things focused, common Connect peer patterns are omitted, including:

  • Attachment acceptance workflows (AttachmentAccepter)
  • Core network address configuration (coreNetworkAddress)
  • Resource tagging (tags)
  • Multi-peer configurations

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

Let's configure AWS Network Manager Connect Peers

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

Try Pulumi Cloud for FREE

Frequently Asked Questions

Configuration & Requirements
What configuration is required for different Connect attachment protocols?

The required configuration depends on the protocol:

  • GRE protocol: Requires insideCidrBlocks for BGP peering IP addresses
  • NO_ENCAP protocol (tunnel-less): Requires subnetArn instead of insideCidrBlocks
How do I configure BGP peering for a Connect peer?
Set the required bgpOptions property with the peer ASN. For example, bgpOptions: { peerAsn: "65000" }. This property is immutable after creation.
Immutability & Updates
What properties can't I change after creating a Connect peer?
The following properties are immutable and require resource replacement if changed: bgpOptions, connectAttachmentId, peerAddress, coreNetworkAddress, and insideCidrBlocks.
Dependencies & Ordering
When do I need to use AttachmentAccepter with Connect peers?
Use aws.networkmanager.AttachmentAccepter with dependsOn when you need to ensure attachments are accepted before creating the Connect peer, as shown in the attachment accepter example.
Networking & Addresses
What's the difference between peerAddress and coreNetworkAddress?
peerAddress (required) is the Connect peer’s address, while coreNetworkAddress (optional) is the core network’s address for the BGP session.

Using a different cloud?

Explore networking guides for other cloud providers: