|
| 1 | +# Working with VPC peering connections using the AWS CLI |
| 2 | + |
| 3 | +This tutorial guides you through the process of creating and configuring VPC peering connections using the AWS Command Line Interface (AWS CLI). VPC peering enables direct network connectivity between two VPCs, allowing resources in each VPC to communicate with each other as if they were on the same network. |
| 4 | + |
| 5 | +## Prerequisites |
| 6 | + |
| 7 | +Before you begin this tutorial, make sure you have the following: |
| 8 | + |
| 9 | +1. The AWS CLI installed and configured with appropriate credentials. If you need to install it, follow the [AWS CLI installation guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). |
| 10 | +2. Permissions to create and manage VPC resources in your AWS account. |
| 11 | +3. Basic understanding of VPC networking concepts. |
| 12 | +4. Two existing VPCs with non-overlapping CIDR blocks. If you don't have existing VPCs, you can create them as shown in the first section of this tutorial. |
| 13 | + |
| 14 | +### Cost considerations |
| 15 | + |
| 16 | +The resources used in this tutorial have the following cost implications: |
| 17 | + |
| 18 | +- VPCs, subnets, route tables, and VPC peering connections within the same region are free of charge. |
| 19 | +- If you create VPC peering connections between different regions, you will incur data transfer charges for traffic that flows across the peering connection. |
| 20 | +- Any EC2 instances or other resources you launch within these VPCs will incur standard charges. |
| 21 | +- Data transfer between instances in different Availability Zones will incur standard EC2 data transfer charges, even when using VPC peering. |
| 22 | + |
| 23 | +For the most up-to-date pricing information, refer to the [Amazon VPC Pricing](https://aws.amazon.com/vpc/pricing/) page. |
| 24 | + |
| 25 | +## Create VPCs for peering |
| 26 | + |
| 27 | +If you don't already have VPCs to use for this tutorial, you can create them using the AWS CLI. The VPCs must have non-overlapping CIDR blocks to establish a peering connection. |
| 28 | + |
| 29 | +**Create the first VPC** |
| 30 | + |
| 31 | +The following command creates a VPC with a CIDR block of 10.0.0.0/16: |
| 32 | + |
| 33 | +```bash |
| 34 | +VPC1_ID=$(aws ec2 create-vpc \ |
| 35 | + --cidr-block 10.0.0.0/16 \ |
| 36 | + --tag-specifications "ResourceType=vpc,Tags=[{Key=Name,Value=VPC1}]" \ |
| 37 | + --query 'Vpc.VpcId' \ |
| 38 | + --output text) |
| 39 | + |
| 40 | +echo "VPC1 created with ID: $VPC1_ID" |
| 41 | +``` |
| 42 | + |
| 43 | +After running this command, the VPC ID is stored in the `VPC1_ID` variable and displayed in the terminal. This VPC will be the requester in our peering connection. |
| 44 | + |
| 45 | +**Create a subnet in the first VPC** |
| 46 | + |
| 47 | +Now, let's create a subnet within the first VPC: |
| 48 | + |
| 49 | +```bash |
| 50 | +SUBNET1_ID=$(aws ec2 create-subnet \ |
| 51 | + --vpc-id $VPC1_ID \ |
| 52 | + --cidr-block 10.0.1.0/24 \ |
| 53 | + --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=VPC1-Subnet}]" \ |
| 54 | + --query 'Subnet.SubnetId' \ |
| 55 | + --output text) |
| 56 | + |
| 57 | +echo "Subnet created in VPC1 with ID: $SUBNET1_ID" |
| 58 | +``` |
| 59 | + |
| 60 | +This command creates a subnet with CIDR block 10.0.1.0/24 within the first VPC. The subnet ID is stored in the `SUBNET1_ID` variable. |
| 61 | + |
| 62 | +**Create the second VPC** |
| 63 | + |
| 64 | +Next, create the second VPC with a different CIDR block: |
| 65 | + |
| 66 | +```bash |
| 67 | +VPC2_ID=$(aws ec2 create-vpc \ |
| 68 | + --cidr-block 172.16.0.0/16 \ |
| 69 | + --tag-specifications "ResourceType=vpc,Tags=[{Key=Name,Value=VPC2}]" \ |
| 70 | + --query 'Vpc.VpcId' \ |
| 71 | + --output text) |
| 72 | + |
| 73 | +echo "VPC2 created with ID: $VPC2_ID" |
| 74 | +``` |
| 75 | + |
| 76 | +This command creates a second VPC with CIDR block 172.16.0.0/16. The VPC ID is stored in the `VPC2_ID` variable. This VPC will be the accepter in our peering connection. |
| 77 | + |
| 78 | +**Create a subnet in the second VPC** |
| 79 | + |
| 80 | +Create a subnet within the second VPC: |
| 81 | + |
| 82 | +```bash |
| 83 | +SUBNET2_ID=$(aws ec2 create-subnet \ |
| 84 | + --vpc-id $VPC2_ID \ |
| 85 | + --cidr-block 172.16.1.0/24 \ |
| 86 | + --tag-specifications "ResourceType=subnet,Tags=[{Key=Name,Value=VPC2-Subnet}]" \ |
| 87 | + --query 'Subnet.SubnetId' \ |
| 88 | + --output text) |
| 89 | + |
| 90 | +echo "Subnet created in VPC2 with ID: $SUBNET2_ID" |
| 91 | +``` |
| 92 | + |
| 93 | +This command creates a subnet with CIDR block 172.16.1.0/24 within the second VPC. The subnet ID is stored in the `SUBNET2_ID` variable. |
| 94 | + |
| 95 | +## Create a VPC peering connection |
| 96 | + |
| 97 | +After creating the VPCs and subnets (or if you're using existing VPCs), you can establish a VPC peering connection between them. |
| 98 | + |
| 99 | +**Create the peering connection** |
| 100 | + |
| 101 | +The following command creates a VPC peering connection from the first VPC to the second VPC: |
| 102 | + |
| 103 | +```bash |
| 104 | +PEERING_ID=$(aws ec2 create-vpc-peering-connection \ |
| 105 | + --vpc-id $VPC1_ID \ |
| 106 | + --peer-vpc-id $VPC2_ID \ |
| 107 | + --tag-specifications "ResourceType=vpc-peering-connection,Tags=[{Key=Name,Value=VPC1-VPC2-Peering}]" \ |
| 108 | + --query 'VpcPeeringConnection.VpcPeeringConnectionId' \ |
| 109 | + --output text) |
| 110 | + |
| 111 | +echo "VPC Peering Connection created with ID: $PEERING_ID" |
| 112 | +``` |
| 113 | + |
| 114 | +This command initiates a peering connection request from VPC1 to VPC2. The peering connection ID is stored in the `PEERING_ID` variable. The peering connection is in the `pending-acceptance` state until it's accepted by the owner of the accepter VPC. |
| 115 | + |
| 116 | +## Accept the VPC peering connection |
| 117 | + |
| 118 | +For the peering connection to become active, it must be accepted by the owner of the accepter VPC. In this tutorial, since we're using the same AWS account for both VPCs, we can accept the request ourselves. |
| 119 | + |
| 120 | +**Accept the peering request** |
| 121 | + |
| 122 | +Use the following command to accept the VPC peering connection: |
| 123 | + |
| 124 | +```bash |
| 125 | +aws ec2 accept-vpc-peering-connection \ |
| 126 | + --vpc-peering-connection-id $PEERING_ID |
| 127 | +``` |
| 128 | + |
| 129 | +After running this command, the VPC peering connection status changes from `pending-acceptance` to `active`. The VPCs are now peered, but you still need to configure route tables to enable traffic flow between them. |
| 130 | + |
| 131 | +## Update route tables |
| 132 | + |
| 133 | +To enable traffic between the peered VPCs, you need to update the route tables for both VPCs to route traffic destined for the peer VPC through the peering connection. |
| 134 | + |
| 135 | +**Create a route table for the first VPC** |
| 136 | + |
| 137 | +First, create a route table for VPC1: |
| 138 | + |
| 139 | +```bash |
| 140 | +RTB1_ID=$(aws ec2 create-route-table \ |
| 141 | + --vpc-id $VPC1_ID \ |
| 142 | + --tag-specifications "ResourceType=route-table,Tags=[{Key=Name,Value=VPC1-RouteTable}]" \ |
| 143 | + --query 'RouteTable.RouteTableId' \ |
| 144 | + --output text) |
| 145 | + |
| 146 | +echo "Route table created for VPC1 with ID: $RTB1_ID" |
| 147 | +``` |
| 148 | + |
| 149 | +This command creates a new route table for VPC1 and stores its ID in the `RTB1_ID` variable. |
| 150 | + |
| 151 | +**Create a route from VPC1 to VPC2** |
| 152 | + |
| 153 | +Add a route to the VPC1 route table that directs traffic destined for VPC2's CIDR block through the peering connection: |
| 154 | + |
| 155 | +```bash |
| 156 | +aws ec2 create-route \ |
| 157 | + --route-table-id $RTB1_ID \ |
| 158 | + --destination-cidr-block 172.16.0.0/16 \ |
| 159 | + --vpc-peering-connection-id $PEERING_ID |
| 160 | +``` |
| 161 | + |
| 162 | +This command creates a route in VPC1's route table that sends traffic destined for VPC2's CIDR block (172.16.0.0/16) through the VPC peering connection. |
| 163 | + |
| 164 | +**Associate the route table with the subnet in VPC1** |
| 165 | + |
| 166 | +Associate the route table with the subnet in VPC1: |
| 167 | + |
| 168 | +```bash |
| 169 | +RTB1_ASSOC_ID=$(aws ec2 associate-route-table \ |
| 170 | + --route-table-id $RTB1_ID \ |
| 171 | + --subnet-id $SUBNET1_ID \ |
| 172 | + --query 'AssociationId' \ |
| 173 | + --output text) |
| 174 | + |
| 175 | +echo "Route table associated with subnet in VPC1" |
| 176 | +``` |
| 177 | + |
| 178 | +This command associates the route table with the subnet in VPC1, enabling the subnet to use the routes defined in the route table. |
| 179 | + |
| 180 | +**Create a route table for the second VPC** |
| 181 | + |
| 182 | +Now, create a route table for VPC2: |
| 183 | + |
| 184 | +```bash |
| 185 | +RTB2_ID=$(aws ec2 create-route-table \ |
| 186 | + --vpc-id $VPC2_ID \ |
| 187 | + --tag-specifications "ResourceType=route-table,Tags=[{Key=Name,Value=VPC2-RouteTable}]" \ |
| 188 | + --query 'RouteTable.RouteTableId' \ |
| 189 | + --output text) |
| 190 | + |
| 191 | +echo "Route table created for VPC2 with ID: $RTB2_ID" |
| 192 | +``` |
| 193 | + |
| 194 | +This command creates a new route table for VPC2 and stores its ID in the `RTB2_ID` variable. |
| 195 | + |
| 196 | +**Create a route from VPC2 to VPC1** |
| 197 | + |
| 198 | +Add a route to the VPC2 route table that directs traffic destined for VPC1's CIDR block through the peering connection: |
| 199 | + |
| 200 | +```bash |
| 201 | +aws ec2 create-route \ |
| 202 | + --route-table-id $RTB2_ID \ |
| 203 | + --destination-cidr-block 10.0.0.0/16 \ |
| 204 | + --vpc-peering-connection-id $PEERING_ID |
| 205 | +``` |
| 206 | + |
| 207 | +This command creates a route in VPC2's route table that sends traffic destined for VPC1's CIDR block (10.0.0.0/16) through the VPC peering connection. |
| 208 | + |
| 209 | +**Associate the route table with the subnet in VPC2** |
| 210 | + |
| 211 | +Associate the route table with the subnet in VPC2: |
| 212 | + |
| 213 | +```bash |
| 214 | +RTB2_ASSOC_ID=$(aws ec2 associate-route-table \ |
| 215 | + --route-table-id $RTB2_ID \ |
| 216 | + --subnet-id $SUBNET2_ID \ |
| 217 | + --query 'AssociationId' \ |
| 218 | + --output text) |
| 219 | + |
| 220 | +echo "Route table associated with subnet in VPC2" |
| 221 | +``` |
| 222 | + |
| 223 | +This command associates the route table with the subnet in VPC2, enabling the subnet to use the routes defined in the route table. |
| 224 | + |
| 225 | +## Verify the VPC peering connection |
| 226 | + |
| 227 | +After setting up the VPC peering connection and configuring the route tables, you should verify that the connection is active and properly configured. |
| 228 | + |
| 229 | +**Check the peering connection status** |
| 230 | + |
| 231 | +Use the following command to check the status of the VPC peering connection: |
| 232 | + |
| 233 | +```bash |
| 234 | +aws ec2 describe-vpc-peering-connections \ |
| 235 | + --vpc-peering-connection-ids $PEERING_ID |
| 236 | +``` |
| 237 | + |
| 238 | +The output should show the status as "active", indicating that the peering connection is established and working. You should also see details about both the requester and accepter VPCs. |
| 239 | + |
| 240 | +## Clean up resources |
| 241 | + |
| 242 | +When you no longer need the VPC peering connection and associated resources, you should clean them up to avoid incurring unnecessary charges. |
| 243 | + |
| 244 | +**Delete the VPC peering connection** |
| 245 | + |
| 246 | +To delete the VPC peering connection: |
| 247 | + |
| 248 | +```bash |
| 249 | +aws ec2 delete-vpc-peering-connection \ |
| 250 | + --vpc-peering-connection-id $PEERING_ID |
| 251 | + |
| 252 | +echo "VPC Peering Connection deleted" |
| 253 | +``` |
| 254 | + |
| 255 | +This command deletes the VPC peering connection. Once deleted, traffic can no longer flow between the VPCs through this connection. |
| 256 | + |
| 257 | +**Delete route tables and their associations** |
| 258 | + |
| 259 | +Before deleting the route tables, you need to disassociate them from the subnets: |
| 260 | + |
| 261 | +```bash |
| 262 | +aws ec2 disassociate-route-table \ |
| 263 | + --association-id $RTB2_ASSOC_ID |
| 264 | + |
| 265 | +aws ec2 disassociate-route-table \ |
| 266 | + --association-id $RTB1_ASSOC_ID |
| 267 | +``` |
| 268 | + |
| 269 | +These commands disassociate the route tables from their respective subnets. After disassociating, you can delete the route tables: |
| 270 | + |
| 271 | +```bash |
| 272 | +aws ec2 delete-route-table \ |
| 273 | + --route-table-id $RTB2_ID |
| 274 | + |
| 275 | +aws ec2 delete-route-table \ |
| 276 | + --route-table-id $RTB1_ID |
| 277 | +``` |
| 278 | + |
| 279 | +These commands delete the route tables you created for VPC1 and VPC2. |
| 280 | + |
| 281 | +**Delete subnets** |
| 282 | + |
| 283 | +If you created subnets specifically for this tutorial, you can delete them: |
| 284 | + |
| 285 | +```bash |
| 286 | +aws ec2 delete-subnet \ |
| 287 | + --subnet-id $SUBNET2_ID |
| 288 | + |
| 289 | +aws ec2 delete-subnet \ |
| 290 | + --subnet-id $SUBNET1_ID |
| 291 | +``` |
| 292 | + |
| 293 | +These commands delete the subnets you created in VPC1 and VPC2. |
| 294 | + |
| 295 | +**Delete VPCs** |
| 296 | + |
| 297 | +If you created VPCs specifically for this tutorial, you can delete them: |
| 298 | + |
| 299 | +```bash |
| 300 | +aws ec2 delete-vpc \ |
| 301 | + --vpc-id $VPC2_ID |
| 302 | + |
| 303 | +aws ec2 delete-vpc \ |
| 304 | + --vpc-id $VPC1_ID |
| 305 | +``` |
| 306 | + |
| 307 | +These commands delete the VPCs you created for this tutorial. Note that you can only delete a VPC after all its resources (subnets, route tables, etc.) have been deleted. |
| 308 | + |
| 309 | +## Going to production |
| 310 | + |
| 311 | +This tutorial demonstrates the basic steps to create and configure a VPC peering connection for educational purposes. When implementing VPC peering in a production environment, consider the following additional best practices: |
| 312 | + |
| 313 | +### Security considerations |
| 314 | + |
| 315 | +1. **Configure security groups**: Restrict traffic between peered VPCs by configuring security groups that allow only necessary traffic. For more information, see [Security groups for your VPC](https://docs.aws.amazon.com/vpc/latest/userguide/VPC_SecurityGroups.html). |
| 316 | + |
| 317 | +2. **Implement network ACLs**: Use network ACLs as an additional layer of security at the subnet level. For more information, see [Network ACLs](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-network-acls.html). |
| 318 | + |
| 319 | +3. **Enable VPC Flow Logs**: Monitor traffic between peered VPCs by enabling VPC Flow Logs. For more information, see [VPC Flow Logs](https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html). |
| 320 | + |
| 321 | +4. **Use more specific routes**: Instead of routing entire VPC CIDR blocks, consider creating more specific routes to limit communication to only necessary subnets. |
| 322 | + |
| 323 | +### Architecture considerations |
| 324 | + |
| 325 | +1. **VPC peering limitations**: VPC peering does not support transitive peering, meaning if VPC A is peered with VPC B, and VPC B is peered with VPC C, VPC A cannot communicate with VPC C through VPC B. |
| 326 | + |
| 327 | +2. **Scaling beyond two VPCs**: For complex networks involving multiple VPCs, consider using AWS Transit Gateway instead of creating multiple peering connections. For more information, see [AWS Transit Gateway](https://docs.aws.amazon.com/vpc/latest/tgw/what-is-transit-gateway.html). |
| 328 | + |
| 329 | +3. **High availability**: For critical applications, consider implementing redundant networking paths and monitoring for the VPC peering connection. |
| 330 | + |
| 331 | +4. **DNS resolution**: Enable DNS resolution for VPC peering connections to resolve DNS hostnames to private IP addresses across peered VPCs. For more information, see [Enable DNS resolution for a VPC peering connection](https://docs.aws.amazon.com/vpc/latest/peering/vpc-peering-dns.html). |
| 332 | + |
| 333 | +For comprehensive guidance on building secure and scalable architectures on AWS, refer to the [AWS Well-Architected Framework](https://aws.amazon.com/architecture/well-architected/). |
| 334 | + |
| 335 | +## Next steps |
| 336 | + |
| 337 | +Now that you've learned how to create and configure VPC peering connections using the AWS CLI, you can explore more advanced networking scenarios: |
| 338 | + |
| 339 | +1. [Create a VPC peering connection between VPCs in different regions](https://docs.aws.amazon.com/vpc/latest/peering/vpc-peering-regions.html) to connect resources across AWS regions. |
| 340 | +2. [Enable DNS resolution for VPC peering connections](https://docs.aws.amazon.com/vpc/latest/peering/vpc-peering-dns.html) to resolve DNS hostnames to private IP addresses across peered VPCs. |
| 341 | +3. [Update security groups to reference peer security groups](https://docs.aws.amazon.com/vpc/latest/peering/vpc-peering-security-groups.html) for more granular control over traffic between peered VPCs. |
| 342 | +4. [Explore Transit Gateway](https://docs.aws.amazon.com/vpc/latest/tgw/what-is-transit-gateway.html) for connecting multiple VPCs and on-premises networks through a central hub. |
| 343 | +5. [Learn about VPC endpoints](https://docs.aws.amazon.com/vpc/latest/privatelink/vpc-endpoints.html) to privately connect your VPC to supported AWS services without requiring an internet gateway. |
0 commit comments