What is AWS Prefix actually?

The term prefix list comes from routing technology. An IP address in CIDR format has an IP prefix and a network prefix (10.1.0.0/16). The IP prefix is 10.1 and the network prefix is /16.

Therefore if you are using a list of IP addresses in CIDR format we call it an IP Prefix List.


What is Prefix List in AWS VPC context

Prefix List is the IP ranges in CIDR format which are assigned to the VPC Gateway Endpoint (S3 or DynamoDB) in a region. It is region-specific.

For example, as of 24/Feb, 2020, the prefix list for DynamoDB in the us-east-2 region is "52.94.4.0/24" where 52.94.4 is the IP prefix and the network prefix is /24 as explained by @John Hanley. The IPs the VPC Gateway endpoint for DynamoDB can take is within 52.94.4.1 - 52.94.4.254 (AWS may have reserved some IPs).

$ aws ec2 describe-prefix-lists
{
    "PrefixLists": [
        {
            "Cidrs": [
                "52.94.4.0/24"
            ],
            "PrefixListId": "pl-4ca54025",
            "PrefixListName": "com.amazonaws.us-east-2.dynamodb"
        },
        {
            "Cidrs": [
                "52.219.80.0/20",
                "3.5.128.0/22",
                "3.5.132.0/23",
                "52.219.96.0/20",
                "52.92.76.0/22"
            ],
            "PrefixListId": "pl-7ba54012",
            "PrefixListName": "com.amazonaws.us-east-2.s3"
        }
    ]
}

Those prefix list has an ID and a name. We can specify prefix list ID in a VPC routing table and in a Security Group, but not in NACL. We need to use CIDR for NACL.

enter image description here

  • Gateway VPC Endpoints

    You canNOT use a prefix list ID in an outbound rule in a network ACL to allow or deny outbound traffic to the service specified in an endpoint. If your network ACL rules restrict traffic, you must specify the CIDR block (IP address range) for the service instead. You can, however, use a prefix list ID in an outbound security group rule. For more information, see Security Groups.

Terraform examples

NACL

  • Data Source: aws_prefix_list
resource "aws_vpc_endpoint" "private_s3" {
  vpc_id       = "${aws_vpc.foo.id}"
  service_name = "com.amazonaws.us-west-2.s3"
}

data "aws_prefix_list" "private_s3" {
  prefix_list_id = "${aws_vpc_endpoint.private_s3.prefix_list_id}"
}

resource "aws_network_acl" "bar" {
  vpc_id = "${aws_vpc.foo.id}"
}

resource "aws_network_acl_rule" "private_s3" {
  network_acl_id = "${aws_network_acl.bar.id}"
  rule_number    = 200
  egress         = false
  protocol       = "tcp"
  rule_action    = "allow"
  cidr_block     = "${data.aws_prefix_list.private_s3.cidr_blocks[0]}"
  from_port      = 443
  to_port        = 443
}

Security Group as provided by @LeOn - Han Li in his answer.

resource "aws_security_group_rule" "MyService_to_DynamoDB_east" {
  count = "${ lower(var.region) == "us-east-1" ? 1 : 0 }"

  security_group_id = "${aws_security_group.MyService_Ext_Api.id}"
  description       = "DynamoDB"
  type              = "egress"
  protocol          = "tcp"
  from_port         = 443
  to_port           = 443
  prefix_list_ids    = ["pl-02ad2a6c"]
}

resource "aws_security_group_rule" "MyService_to_DynamoDB_west" {
  count = "${ lower(var.region) == "us-west-2" ? 1 : 0 }"

  security_group_id = "${aws_security_group.MyService_Ext_Api.id}"
  description       = "DynamoDB"
  type              = "egress"
  protocol          = "tcp"
  from_port         = 443
  to_port           = 443
  prefix_list_ids    = ["pl-0ca54061"]
}

Access Control

Why can’t I connect to an S3 bucket using a gateway VPC endpoint? layouts comprehensive list regarding S3 VPC Gateway Endpoint and the prefix list ID and CIDR would play parts there.

  • DNS settings in your VPC
    Important: DNS resolution must be enabled in your VPC (see Gateway Endpoint Limitations). If you're using your own DNS server, be sure DNS requests to AWS services resolve to AWS-maintained IP addresses.
  • Route table settings to Amazon S3
  • Security group outbound rules
  • Network ACL rules
  • Gateway VPC endpoint policy
  • S3 bucket policy
  • IAM policy

References

  • Gateway VPC Endpoints

    Specify the VPC in which to create the endpoint, and the service to which you're connecting. A service is identified by a prefix list—the name and ID of a service for a Region. A prefix list ID uses the form pl-xxxxxxx and a prefix list name uses the form "com.amazonaws.region.service". Use the prefix list name (service name) to create an endpoint.


If what you are looking for is prefix list id for vpc endpoint like dynamodb/s3, then it is not related to IP or CIDR. As it is mentioned in the documentation:

A prefix list ID is required for creating an outbound security group rule that allows traffic from a VPC to access an AWS service through a gateway VPC endpoint.

So if do not have prefix-list id in your security group outbout for ec2 or vpc-lambda, you will get time out when connecting to dynamodb or s3.

You can get the prefix-list by running

aws ec2 describe-prefix-lists

{
    "PrefixLists": [
        {
            "Cidrs": [
                "54.231.0.0/17",
                "52.216.0.0/15"
            ],
            "PrefixListId": "pl-63c5400k",
            "PrefixListName": "com.amazonaws.us-east-1.s3"
        },
        {
            "Cidrs": [
                "52.94.0.0/22",
                "52.119.224.0/20"
            ],
            "PrefixListId": "pl-02ad2a6c",
            "PrefixListName": "com.amazonaws.us-east-1.dynamodb"
        }
    ]
}

Then you can put this PrefixListId into your security group outbound via aws web console. If you use terraform for different region, it could be something like:

resource "aws_security_group_rule" "MyService_to_DynamoDB_east" {
  count = "${ lower(var.region) == "us-east-1" ? 1 : 0 }"

  security_group_id = "${aws_security_group.MyService_Ext_Api.id}"
  description       = "DynamoDB"
  type              = "egress"
  protocol          = "tcp"
  from_port         = 443
  to_port           = 443
  prefix_list_ids    = ["pl-02ad2a6c"]
}

resource "aws_security_group_rule" "MyService_to_DynamoDB_west" {
  count = "${ lower(var.region) == "us-west-2" ? 1 : 0 }"

  security_group_id = "${aws_security_group.MyService_Ext_Api.id}"
  description       = "DynamoDB"
  type              = "egress"
  protocol          = "tcp"
  from_port         = 443
  to_port           = 443
  prefix_list_ids    = ["pl-0ca54061"]
}