Contact
Private property, no trespassing?

Blog

Private property, no trespassing?

Cloud computing is a modern technology and can be widely used. Data backup, virtual desktops, software development, data analysis and testing, just to name a few. Still, some concerns can be found spread across the internet about data property, data security and privacy. However, the Virtual Private Cloud (abbr. VPC) can support here because it is logically isolated from other AWS virtual networks. Thus, AWS resources can be launched into a virtual network that you define to your needs. This virtual network layer for Amazon EC2 is similar to a traditional network but with the advantages of scalable infrastructure. Therefore, its key concepts are subnets, route tables, internet gateways, and endpoints. For routing traffic using IPv4 or IPv6 addresses between VPCs is called VPC peering, but it is not a gateway or a VPN connection. VPC peering connections can be created between different VPCs of your own or between your own and another AWS account’s VPC or even between different regions.

 

Scenarios of VPC Peering

Consider an example, where the following scenarios are given: On the one hand, common, central tools needed for development like GitLab or Artifactory need to be accessed by different teams. On the other hand, some teams need to share their services with others to proceed on a project. Moreover, access is needed for testing purposes to the service(s) to be tested and to the central tools.

 

The scenario of decentralized resource targets to enable full sharing of resources between all VPCs. For instance, considering multiple departments or multiple services owning VPCs each, maybe also in different AWS accounts, but they all should have the same access to resources like in a file-sharing network. This means that the entire CIDR block of the peer VPC(s) needs to be accessed by your route table.

Source: Three VPCs peered together

The scenario of centralized resource targets to enable one or more resourceless VPC(s) partly or fully accessing one resourceful VPC. For instance, consider sharing a VPC with your customers, where a VPC peering connection is created for each customer. Each customer is not aware of the other customers’ routes and the customers cannot route to other VPCs, like in this graph:

Source: One VPC peered with multiple VPCs

For the sake of completeness, the third VPC peering scenario of using ClassicLink targets to enable communication from one or more EC2-Classic instances with instances in the peer VPC by using ClassicLink as shown here:

 

Source: Peering Configuration with ClassicLink

How to peer between resources in two different VPCs

Given the scenario of different accounts and one of them is our testing account which needs to access the others for running test cases. Meaning that we have decentralized resources like the repositories with their own VPC and even their own AWS account. The accounts to be tested allow cross-account peering and are referred to as the accepter accounts and the testing account requests the peering connection and is referred to as the requester account.

 

For the peering connection, you need a peer VPC ID, a peer AWS account ID and a cross-account access role. With this information, we set up provisions of the AWS CloudFormation stacks in the accounts by using AWS::EC2::VPCPeeringConnection. Therefore, we create two templates, one for the accepter account and one for the requester account, and configure the stacks with these templates. We enable Domain Name System (abbr. DNS) resolution within the VPC peering. The DNS resolution for the VPC peering connection is requested for querying from instances in the peer VPC to get the public DNS hostnames resolved to private IP addresses. Therefore, we need to create two AWS CloudFormation templates, one for the accepter account and one for the requester account, and configure the stacks with these templates.

 

Firstly, we need to create a VPC by choosing AWS CloudFormation and Create stack in the AWS Management Console for the accepter account. The provisioning template for the accepter account includes version, description, the peer requester account ID, outputs and to be defined resources like VPC and peer role handling the reference to the peer requester Account ID and policies. Here is an example of how the provisioning template.yaml can look like:

AWSTemplateFormatVersion: 2010-09-09
Description: Create a VPC and an assumable role for cross-account VPC peering.
Parameters:
  PeerRequesterAccountId:
    Type: String
Resources:
  vpc:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: 10.1.0.0/16
      EnableDnsSupport: false
      EnableDnsHostnames: false
      InstanceTenancy: default
  peerRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Principal:
              AWS: !Ref PeerRequesterAccountId
            Action:
              - 'sts:AssumeRole'
            Effect: Allow
      Path: /
      Policies:
        - PolicyName: root
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action: 'ec2:AcceptVpcPeeringConnection'
                Resource: '*'
Outputs:
  VPCId:
    Value: !Ref vpc
  RoleARN:
    Value: !GetAtt 
      - peerRole
      - Arn

Then, type in a stack name and the AWS requester account ID in the PeerRequesterAccountId field and accept the defaults if you like. Furthermore, you can apply more restrictive policies under the policies path.

 

Secondly, create the template to peer the VPC using the requester account. Go to the AWS CloudFormation console and again create a stack with the following template.yaml as counterpart to the above:

AWSTemplateFormatVersion: 2010-09-09
Description: Create a VPC and a VPC Peering connection using the PeerRole to accept.
Parameters:
  PeerVPCAccountId:
    Type: String
  PeerVPCId:
    Type: String
  PeerRoleArn:
    Type: String
Resources:
  vpc:
    Type: 'AWS::EC2::VPC'
    Properties:
      CidrBlock: 10.2.0.0/16
      EnableDnsSupport: false
      EnableDnsHostnames: false
      InstanceTenancy: default
  vpcPeeringConnection:
    Type: 'AWS::EC2::VPCPeeringConnection'
    Properties:
      VpcId: !Ref vpc
      PeerVpcId: !Ref PeerVPCId
      PeerOwnerId: !Ref PeerVPCAccountId
      PeerRoleArn: !Ref PeerRoleArn
Outputs:
  VPCId:
    Value: !Ref vpc
  VPCPeeringConnectionId:
    Value: !Ref vpcPeeringConnection

For enabling the DNS resolution within the VPC peering with the AWS CLI, you can use the following console commands:

One for the accepter:

aws ec2 modify-vpc-peering-connection-options --vpc-peering-connection-id pcx-aaaabbbb --accepter-peering-connection-options AllowDnsResolutionFromRemoteVpc=true

And one for the requester:

aws ec2 modify-vpc-peering-connection-options --vpc-peering-connection-id pcx-aaaabbbb --requester-peering-connection-options AllowDnsResolutionFromRemoteVpc=true

Summary

Recap of the steps done:

  1. Create the cross-account role (accepter account) allowing another account (requester account) to peer and a VPC
  2. Create a VPC and peering connection for the requester account with the before created peer role of the accepter account
  3. Enable DNS resolution for accepter
  4. Enable DNS resolution for requester

Sources