21 Days of AWS using Terraform – Day 17- Introduction to AWS VPC Endpoint using Terraform

Welcome to Day 17 of 21 Days of AWS using Terraform. The topic for today is Introduction to AWS VPC Endpoint using Terraform.

What is VPC EndPoint?

A VPC endpoint enables you to privately connect your VPC to supported AWS services and VPC endpoint services powered by PrivateLink without requiring an internet gateway, NAT device, VPN connection, or AWS Direct Connect connection. Instances in your VPC do not require public IP addresses to communicate with resources in the service. Traffic between your VPC and the other service does not leave the Amazon network.

Endpoints are virtual devices. They are horizontally scaled, redundant, and highly available VPC components that allow communication between instances in your VPC and services without imposing availability risks or bandwidth constraints on your network traffic.

There are two types of VPC endpoints:

  • Interface endpoints(using private links): An interface endpoint is an elastic network interface with a private IP address that serves as an entry point for traffic destined to a supported service
# Supported Services
 Amazon API Gateway
 AWS CloudFormation
 Amazon CloudWatch
 Amazon CloudWatch Events
 Amazon CloudWatch Logs
 AWS CodeBuild
 AWS Config
 Amazon EC2 API
 Elastic Load Balancing API
 Amazon Elastic Container Registry
 Amazon Elastic Container Service
 AWS Key Management Service
 Amazon Kinesis Data Streams
 Amazon SageMaker and Amazon SageMaker Runtime
 Amazon SageMaker Notebook Instance
 AWS Secrets Manager
 AWS Security Token Service
 AWS Service Catalog
 Amazon SNS
 Amazon SQS
 AWS Systems Manager
 Endpoint services hosted by other AWS accounts
 Supported AWS Marketplace partner services 
  • Gateway endpoints: A gateway endpoint is a gateway that is a target for a specified route in your route table, used for traffic destined to a supported AWS service
# Supported Services
* Amazon S3
* DynamoDB

Scenario1: I want to push logs from EC2 private instance(running on Private IP)to CloudWatch Logs.

  • To setup VPC Endpoint
Go to https://us-west-2.console.aws.amazon.com/vpc --> EndPoints
  • Once the endpoint is created you will see an elastic network interface with a private IP address which acts as an entry point for traffic destined to a supported service

Terraform Code

resource "aws_vpc_endpoint" "ec2logs" {
  vpc_id            = "${var.vpc_id}"
  service_name      = "com.amazonaws.us-west-2.logs"
  subnet_ids        = ["${var.private_subnet1}", "${var.private_subnet2}"]
  vpc_endpoint_type = "Interface"

  security_group_ids = [
    "${var.security_group}",
  ]

  policy = <<POLICY
{
    "Statement": [
        {
            "Action": "*",
            "Effect": "Allow",
            "Resource": "*",
            "Principal": "*"
        }
    ]
}
POLICY

  private_dns_enabled = true
}

variables.tf

variable "vpc_id" {}
variable "private_subnet1" {}
variable "private_subnet2" {}
variable "security_group" {}

VPC Endpoint Log Module

module "vpc_endpoint_logs" {
  source          = "./vpc_endpoint_logs"
  vpc_id          = "${module.vpc.vpc_id}"
  private_subnet1 = "${module.vpc.private_subnet1}"
  private_subnet2 = "${module.vpc.private_subnet2}"
  security_group  = "${module.vpc.security_group}"
}

Scenario2: I want to push logs from EC2 private instance(running on Private IP)to AWS S3.

  • In the case of gateway endpoint, you will see the entry in the route table, used for traffic destined to a supported AWS service
resource "aws_vpc_endpoint" "s3" {
  vpc_id       = "${var.vpc_id}"
  service_name = "com.amazonaws.us-west-2.s3"
  route_table_ids = ["${var.route_table}"]
      policy = <<POLICY
{
    "Statement": [
        {
            "Action": "*",
            "Effect": "Allow",
            "Resource": "*",
            "Principal": "*"
        }
    ]
}
POLICY
}

variables.tf

variable "vpc_id" {}
variable "route_table" {}

VPC Endpoint S3 Module

module "vpc_endpoint_s3" {
  source = "./vpc_endpoint_s3"
  vpc_id = "${module.vpc.vpc_id}"
  route_table = "${module.vpc.route_table}"
}

Here we need a little modification to our VPC module, here the output of route table act as an input to VPC endpoint s3 module

output "route_table" {
  value = "${aws_default_route_table.private_route.id}"
}

Limitations

  • Only Support IPv4
  • Support only for the same region
  • Interface endpoints cannot only be accessible via VPC Peering or VPN connection only via Direct Connect.
  • You cannot use an IAM policy or bucket policy to allow access from a VPC IPv4 CIDR range (the private IPv4 address range). VPC CIDR blocks can be overlapping or identical, which may lead to unexpected results. Therefore, you cannot use the aws:SourceIp condition in your IAM policies for requests to Amazon S3 through a VPC endpoint. This applies to IAM policies for users and roles, and any bucket policies. If a statement includes the aws:SourceIp condition, the value fails to match any provided IP address or range

Please join me with my journey by following any of the below links