My first interaction with AWS was immediately after the launch of the Asia Pacific (Sydney) AWS Region, just a bit over 6 years ago. Back then, the AWS Management Console had fewer services, and I quickly found the Amazon Virtual Private Cloud (VPC). In under 10 minutes, I could define a new VPC, with subnets, routing and, internet gateway. It was magic. Before Amazon VPC, it would take over 10 minutes to unpack boxes with some networking equipment like firewalls and switches. Months were spent before that figuring out network topology, looking up specifications, going over quotes, ordering, and hoping everything you needed would arrive in time. A few iterations of firmware upgrades, initial configuration, and days later you could have something that resembled a VPC. With the coming of Amazon VPC, I felt the power of software-defined networking that extended beyond familiar server virtualization of network interfaces.

Fast forward to the present day, in which most AWS customers use multiple AWS accounts. It makes absolute sense from a security and blast radius perspective. As an additional benefit, billing is per account, so some customers use it to allocate costs. Over the years AWS has made managing multi-account AWS environments easier. We’ve introduced consolidated billing, AWS Organizations, cross-account IAM roles delegation, and various ways to share resources like snapshots, AMIs, etc.

One thing that remains a constant, VPCs are always per account. It means that networks have to be partitioned and each new account had to have its own VPC in every Region. Having a segregated network means that customers now need a way to connect from one VPC to another. To do this, we built VPC Peering. It does the job when you have a few VPCs, but some of our customers have hundreds and even thousands of VPCs. Also, connectivity back to your own data center, for hybrid environments, increases in complexity with each new VPC. We recently introduced AWS Transit Gateway to solve this.

To quote from Jeff Bezos’s 2016 letter to shareholders, “Customers are always beautifully, wonderfully dissatisfied.” We are always looking for ways to improve our customers’ experiences. Customers told us that a form of central control over VPC management is needed. They also asked for ways to simplify IPv4 allocation and preserve IP addresses. Many modern applications require a high degree of interconnectivity between components (microservices).

It’s time to reconsider the “VPC per account” architecture.

Introducing VPC sharing

VPC sharing allows customers to share subnets with other AWS accounts within the same AWS Organization. This is a very powerful concept that allows for a number of benefits:

Separation of duties: centrally controlled VPC structure, routing, IP address allocation.

Application owners continue to own resources, accounts, and security groups.

VPC sharing participants can reference security group IDs of each other.

Efficiencies: higher density in subnets, efficient use of VPNs and AWS Direct Connect.

Hard limits can be avoided, for example, 50 VIFs per AWS Direct Connect connection through simplified network architecture.

Costs can be optimized through reuse of NAT gateways, VPC interface endpoints, and intra-Availability Zone traffic.

Essentially, we can now decouple accounts and networks. I expect customers to continue to have multiple VPCs even with VPC sharing. But they can now have fewer, larger, centrally managed VPCs. Highly interconnected apps automatically benefit from this approach.

In this blog post I’ll show you how VPC sharing works..

Setting up VPC sharing

VPC sharing makes use of recently launched AWS Resource Access Manager (AWS RAM). As Jeff Barr has pointed out in his post, we have been busy adding more resource types into AWS RAM. We have added AWS Transit Gateway, Amazon Route 53 resolver rules, license configurations, and now VPC subnets.

If you have not used AWS RAM before, you must enable it from the master account of your AWS Organization.

In AWS RAM, we can create resource shares, which are like buckets where different resources can be shared with the entire AWS Organization, Organizational Units (OUs), or AWS accounts. Remember that subnets can only be shared within the same AWS Organization.

I have created two new accounts with AWS Organizations, and I gave myself access via AWS Single Sign-On (SSO).

I will now use account 1A to create a new VPC. This account will manage VPC configuration, in other words it is a VPC owner. The VPC owner will share subnets with other accounts that we call VPC participants. In my example, account 1B is the VPC participant.

I will use a handy VPC Quick Start to set up my VPC, subnets, and routing.

Next, I’ll use AWS RAM to create my resource share. I’ll give it the name “DEVELOPMENT” because the VPC I created earlier is going to host some development workloads.

At this stage, selecting resources and adding principals (actual accounts to share with) is optional. I did however populate a 12-digit account ID for a VPC participant to save some time later.

Now I can navigate to the Amazon VPC console subnet page and share subnets from there.

I complete sharing by selecting the Resource Share I want to share with.

There is also a new Sharing tab where I can see my sharing status.

I can share additional subnets from either AWS RAM or the Amazon VPC console subnets page. I can also remove sharing. When sharing is removed the participant will no longer be able to launch any new resources into shared subnets. Resources will continue to run until the participant decides to terminate them. It gives time to the participant to gracefully exit and safeguards from accidental disruption.

Now I will pretend to be an application owner who wants to launch a brand new EC2 instance into my newly shared VPC. In other words, I will switch over to the VPC participant account. I switch over and proceed to launch an EC2 instance like I normally would. I’m also able to see our shared subnet in the console:

And I can also see an annotation next to VPC ID stating that it is being shared.

Earlier, I launched another EC2 instance from within the VPC owner account. Now I want to allow access from it into my EC2 instance running in the participant account. To do that, I use the security group ID from the VPC owner account. Simply adding it to as a source is sufficient. Note how the owner of the security group has one account ID and the source has a different account ID.

Finally, I’m ready to test connectivity. Since every VPC has an implicit router, I don’t need to do any routing configuration.

I have also kept both instances within the same Availability Zone. Although traffic originates from one account to a resource in another account, there is no cost since both are sharing the same VPC and physical location. I can also see both network interfaces within the VPC owner account and corresponding owner IDs.

A careful reader may have noticed that VPC owner has the subnet in us-east-1a but VPC participant shows it as us-east-1c. More on that later in this blog post.

As part of this launch, we also released some additional attributes for Amazon EC2 APIs: OwnerId, which indicates if the resource is owned by your own account or shared with you, and AvailabilityZoneId (AZ ID). Most customers already know that AWS aims to distribute resources across Availability Zones for an AWS Region, and AWS independently maps Availability Zones to data centers for each account. For example, the Availability Zone us-east-1a for your AWS account might not be the same as us-east-1a for another AWS account.

To coordinate Availability Zones across accounts for VPC sharing, you must use the AZ ID, which is a unique and consistent identifier for an Availability Zone. For example, use1-az1 is one of the Availability Zones in the us-east-1 Region. Availability Zone IDs enable you to determine the location of resources in one account relative to the resources in another account. You can see your “true” AZ mapping from the AWS RAM console.

A shared VPC, just like any other VPC, can integrate with AWS PrivateLink, AWS Transit Gateway, and VPC peering. There is no one-size-fits-all, and customers can choose to use existing networking services and constructs in addition to VPC sharing. My colleagues have done an excellent job covering network architectures at the 2018 AWS re:Invent conference: See Best Practices for AWS PrivateLink and Reference Architectures for Many VPCs.

Access control, permissions, and troubleshooting

VPC owners are responsible for creating, managing and deleting all VPC-level resources including subnets, route tables, network ACLs, peering connections, VPC endpoints, AWS PrivateLink endpoints, internet gateways, NAT gateways, virtual private gateways, and transit gateway attachments. A VPC owner cannot delete, modify or forcefully eject a participant’s resources. VPC owners can view the details for all the network interfaces, and the security groups that are attached to the participant resources in order to facilitate troubleshooting, and auditing. VPC owners can create flow log subscriptions at the VPC, subnet, or ENI level for traffic monitoring or troubleshooting.

VPC participants are responsible for the creation, management, and deletion of their resources. Participants cannot view or modify resources that belong to other participant accounts. They can view the details of the route tables, and network ACLs that are attached to the subnets shared with them. However, they cannot modify VPC-level resources including route tables, network ACLs, or subnets. Participants can reference security groups that belong to other participants or the owner using the security group ID. Participants can only create flow log subscriptions for the interfaces that they own.

Customers might find it useful to have Service Control Policies (SCPs) to deny participants access to create their own VPCs. In an ideal world, a newly created account is placed into an Organization Unit (OU) and automatically receives a network baseline in a form of shared VPCs. A similar approach can be incorporated with the AWS Landing Zone and account vending capability.

I created an SCP and applied it to my VPC participant account, as follows, to deny ability to create a new VPC.

As expected, I could no longer create a new VPC from the participant account even with full IAM admin permissions.

When not to use VPC sharing

The beauty of software-defined networking is that you can pick the right approach and combination of features that suites your organization. While many organizations can benefit from VPC sharing, there are scenarios where it is best to continue with one VPC per account:

Separate VPCs provide the highest degree of isolation.

Spinning off a business unit is easier if they own their VPC. You simply disconnect their AWS account from the AWS Organization and sever connectivity.

Application owners that prefer to own the full stack will continue to prefer their own VPCs.

Things to know

VPC sharing is only available within the same AWS Organization.

Sharing of default VPCs/subnets is not possible.

Participants can’t launch resources using security groups that are owned by other participants or the owner.

Participants can’t launch resources using the default security group for the VPC because it belongs to the owner.

Participants pay for their resources and also pay for data transfer charges associated with Inter-Availability Zone data transfer, internet gateway, VPC peering connections, and data transfer through an AWS Direct Connect.

VPC owners pay hourly charges (where applicable), data processing and data transfer charges across NAT gateways, virtual private gateways, transit gateways, AWS PrivateLink, and VPC endpoints.

Currently few services cannot use shared subnets.

Available now

VPC sharing is available in all commercial AWS Regions except for South America (São Paulo), Asia Pacific (Osaka-Local), and China Regions. There are no additional charges for using this functionality. For more information about VPC sharing, see our documentation.