Skip to content

VPC endpoints - #120

Merged
mabadir merged 3 commits into
mainfrom
mabadir/vpc-endpoints
Aug 20, 2026
Merged

VPC endpoints#120
mabadir merged 3 commits into
mainfrom
mabadir/vpc-endpoints

Conversation

@mabadir

@mabadir mabadir commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds optional S3 and DynamoDB gateway endpoints plus selectable AWS PrivateLink interface endpoints to the VPC module.

  • Creates gateway endpoints across the VPC route tables.
  • Creates interface endpoints in private subnets with a shared HTTPS security group and private DNS.
  • Exposes endpoint inputs and outputs through Terraform, the Ravion definition, and module documentation.
  • Updates the module definition release to v1.1.0 and raises the generated lockfile constraint to AWS provider 6.x.

Confidence Score: 4/5

The PR should not merge until interface endpoints reject or support DNS-disabled VPC configurations; the documentation example should also reference the endpoint-capable release.

Interface endpoints always request private DNS while the module still permits either required VPC DNS attribute to be disabled, producing an AWS apply failure for a supported input combination; separately, the new example pins a release that lacks its endpoint arguments.

Files Needing Attention: networking/vpc/vpc_endpoints.tf, networking/vpc/variables.tf, networking/vpc/README.md

Important Files Changed

Filename Overview
networking/vpc/vpc_endpoints.tf Adds gateway and interface VPC endpoints, but the unconditional private-DNS setting is incompatible with supported DNS-disabled VPC configurations.
networking/vpc/variables.tf Adds endpoint controls and service-name validation; the interface-endpoint input does not enforce its documented VPC DNS prerequisites.
networking/vpc/outputs.tf Exposes nullable gateway endpoint and security-group IDs plus the interface endpoint ID map without an identified defect.
networking/vpc/rvn-aws-network-definition.yml Publishes the endpoint inputs and stack mappings as release v1.1.0 without an independently established defect.
networking/vpc/README.md Documents endpoint behavior and inputs, but the new usage example references v1.0.0 rather than the endpoint-capable v1.1.0 release.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Input[Endpoint inputs] --> Gateway{Gateway endpoints enabled?}
  Gateway -->|S3| S3[S3 gateway endpoint]
  Gateway -->|DynamoDB| DDB[DynamoDB gateway endpoint]
  S3 --> Routes[Public and private route tables]
  DDB --> Routes
  Input --> Interface{Interface services nonempty?}
  Interface --> SG[Shared HTTPS security group]
  Interface --> VPCE[Interface endpoints]
  SG --> VPCE
  PrivateSubnets[Private subnets] --> VPCE
  VPCE --> PrivateDNS[Private DNS enabled]
  VPCDNS[VPC DNS support and hostnames] -. required .-> PrivateDNS
Loading
Prompt To Fix All With AI
### Issue 1
networking/vpc/vpc_endpoints.tf:67
**Private DNS prerequisites unenforced**

When a caller enables interface endpoints while setting `dns_support_enabled` or `dns_hostnames_enabled` to false, every endpoint still enables private DNS, causing AWS to reject endpoint creation during apply.

### Issue 2
networking/vpc/README.md:90
**Endpoint example pins old release**

The new VPC-endpoint example pins `v1.0.0`, which predates the endpoint arguments shown below it, so copying the example produces unsupported-argument errors instead of creating endpoints.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "feat(vpc): enable S3 gateway endpoint by..." | Re-trigger Greptile

Greptile also left 2 inline comments on this PR.

Add free S3 and DynamoDB gateway endpoints attached to all route tables,
plus selectable interface endpoints (PrivateLink) placed in private
subnets with private DNS and a shared HTTPS security group. Expose all
three as inputs on the rvn-aws-network definition (1.1.0).
@mabadir
mabadir requested a review from flybayer August 20, 2026 18:49
@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown

Ravion Module Publish Plan

Dry run only. No Ravion API mutations were made.

Module Current Version New Version Description
rvn-aws-network 1.0.1 1.1.0 Add VPC endpoints, a free S3 gateway endpoint enabled by default for new VPCs, an optional DynamoDB gateway endpoint, and selectable interface endpoints for private access to AWS services.

Diffs

rvn-aws-network 1.0.1 -> 1.1.0

--- remote
+++ compiled
     label: NAT gateway Elastic IP allocation IDs
     required: false
     type: string_array
+  - id: section_vpc_endpoints
+    label: VPC endpoints
+    type: section
+  - collapsible: true
+    default: true
+    description: Route S3 traffic through a free gateway VPC endpoint instead of the NAT gateway. Avoids NAT data processing charges (including ECR image layer pulls) and keeps S3 traffic inside AWS.
+    id: vpc_endpoint_s3_gateway_enabled
+    label: S3 gateway endpoint
+    type: boolean
+  - collapsible: true
+    default: false
+    description: Route DynamoDB traffic through a free gateway VPC endpoint instead of the NAT gateway.
+    id: vpc_endpoint_dynamodb_gateway_enabled
+    label: DynamoDB gateway endpoint
+    type: boolean
+  - collapsible: true
+    description: |-
+      Create interface VPC endpoints (AWS PrivateLink) in the private subnets for private access to AWS services without a NAT gateway.
+
+      Each endpoint costs about $8/month per AZ plus data processing charges, so a multi-service set can cost more than a NAT gateway. Pulling ECR images privately requires ECR API, ECR Docker registry, and the S3 gateway endpoint together.
+    id: vpc_endpoint_interface_services
+    label: Interface endpoints
+    required: false
+    type: string_array
+    values:
+      - label: ECR API
+        value: ecr.api
+      - label: ECR Docker registry
+        value: ecr.dkr
+      - label: CloudWatch Logs
+        value: logs
+      - label: CloudWatch metrics
+        value: monitoring
+      - label: Secrets Manager
+        value: secretsmanager
+      - label: Systems Manager
+        value: ssm
+      - label: Systems Manager Session Manager
+        value: ssmmessages
+      - label: EC2 messages
+        value: ec2messages
+      - label: KMS
+        value: kms
+      - label: STS
+        value: sts
+      - label: SQS
+        value: sqs
+      - label: SNS
+        value: sns
+      - label: EventBridge
+        value: events
   - id: section_soc2
     label: SOC 2
     type: section
@@
 
   - **Public and private subnets** across multiple availability zones for high availability
   - **NAT Gateway** options for outbound internet access from private subnets
+  - **VPC endpoints** for private access to S3, DynamoDB, and other AWS services
   - **VPC Flow Logs** for network traffic monitoring and SOC 2 compliance
   - **VPC Peering** to connect with existing VPCs across accounts or regions
 
-   Terraform source: [ravionhq/modules/networking/vpc](https://github.com/ravionhq/modules/tree/rvn-aws-network@1.0.1/networking/vpc)
+   Terraform source: [ravionhq/modules/networking/vpc](https://github.com/ravionhq/modules/tree/rvn-aws-network@1.1.0/networking/vpc)
 
   ## Use cases
 
@@
   | SOC 2 compliance             | Enabling flow logs for network traffic auditing            |
   | Multi-region architecture    | Peering VPCs across regions for low-latency communication  |
   | Partner IP allowlisting      | Using stable NAT Gateway IPs with pre-allocated EIPs       |
+  | Reducing NAT data charges    | Routing S3/DynamoDB traffic through free gateway endpoints |
 
   ## Subnet types
 
@@
 
   To keep the same IP permanently, create your Elastic IPs separately and pass in the allocation IDs. This way, even if you destroy and recreate the entire VPC, your NAT Gateway will use the same public IP — no need to update partner allowlists or firewall rules.
 
+  ## VPC endpoints
+
+  VPC endpoints let resources in the VPC reach AWS services without traversing the internet or the NAT gateway.
+
+  ### Gateway endpoints (free)
+
+  Gateway endpoints for **S3** and **DynamoDB** are free and simply add routes to the VPC's route tables. The S3 gateway endpoint is enabled by default for new VPCs: it keeps S3 traffic — including ECR image layer downloads — off the NAT gateway, cutting NAT data processing charges.
+
+  One caveat: S3 traffic no longer exits through the NAT gateway's public IP, so S3 bucket policies that allowlist your NAT IP need to be updated (for example to match the endpoint via `aws:SourceVpce`).
+
+  ### Interface endpoints (PrivateLink)
+
+  Interface endpoints provide private connectivity to most other AWS services (ECR, CloudWatch Logs, Secrets Manager, Systems Manager, and more). The module places each endpoint in every private subnet with private DNS enabled and a shared security group allowing HTTPS from within the VPC, so AWS SDKs work without configuration changes.
+
+  | Consideration   | Detail                                                                |
+  | --------------- | --------------------------------------------------------------------- |
+  | Cost            | ~$8/month per endpoint per AZ, plus $0.01/GB processed                |
+  | ECR without NAT | Requires ECR API + ECR Docker registry + the S3 gateway endpoint      |
+  | Region scope    | Endpoints connect to services in the VPC's own region only            |
+
+  A typical ECS bundle (ECR API, ECR Docker registry, CloudWatch Logs, Secrets Manager) across 3 AZs runs ~$96/month — more than a single NAT gateway (~$32/month). Choose interface endpoints for private networking and compliance requirements rather than cost savings.
+
   ## Configuration
 
   | Field                          | Required | Default              | Description                                                            |
@@
   | NAT Gateway                    | No       | `true`               | Enable outbound internet from private subnets                          |
   | NAT Gateway High Availability  | No       | `false`              | Deploy one NAT per AZ instead of a single shared NAT                   |
   | NAT Gateway EIP Allocation IDs | No       | —                    | Pre-allocated EIPs for stable NAT public IPs                           |
+  | S3 gateway endpoint            | No       | `true`               | Free gateway endpoint keeping S3 traffic off the NAT gateway           |
+  | DynamoDB gateway endpoint      | No       | `false`              | Free gateway endpoint keeping DynamoDB traffic off the NAT gateway     |
+  | Interface endpoints            | No       | —                    | Interface VPC endpoints (PrivateLink) for private AWS service access   |
   | Flow Logs                      | No       | `false`              | Enable VPC Flow Logs (required for SOC 2)                              |
   | Tags                           | No       | Environment, Project | Custom tags applied to all resources                                   |
 
@@
         base_path: networking/vpc
         branch: main
         execution_environment_id: << module.input.execution_environment_id >>
-        ref: rvn-aws-network@1.0.1
+        ref: rvn-aws-network@1.1.0
         repo: https://github.com/ravionhq/modules
         stack_id: <<stack.id>>
         terraform_variables:
@@
             Owner: Ravion
             ProjectGivenId: <<project.given_id>>
           vpc_cidr: << module.input.vpc_cidr >>
+          vpc_endpoint_dynamodb_gateway_enabled: << module.input.vpc_endpoint_dynamodb_gateway_enabled >>
+          vpc_endpoint_interface_services: << module.input.vpc_endpoint_interface_services >>
+          vpc_endpoint_s3_gateway_enabled: << module.input.vpc_endpoint_s3_gateway_enabled >>
           vpc_peering_connections: << module.input.vpc_peering_connections >>
         tool: opentofu
         tool_version: << module.input.opentofu_version || defaults.opentofu_version >>

vpc_endpoint_type = "Interface"
subnet_ids = aws_subnet.private[*].id
security_group_ids = [aws_security_group.vpc_endpoints[0].id]
private_dns_enabled = true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Private DNS prerequisites unenforced

When a caller enables interface endpoints while setting dns_support_enabled or dns_hostnames_enabled to false, every endpoint still enables private DNS, causing AWS to reject endpoint creation during apply.

Prompt To Fix With AI
This is a comment left during a code review.
Path: networking/vpc/vpc_endpoints.tf
Line: 67

Comment:
**Private DNS prerequisites unenforced**

When a caller enables interface endpoints while setting `dns_support_enabled` or `dns_hostnames_enabled` to false, every endpoint still enables private DNS, causing AWS to reject endpoint creation during apply.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Comment thread networking/vpc/README.md
The list length must equal `1` when `nat_gateway_high_availability_enabled = false`, or the resolved subnet count when `nat_gateway_high_availability_enabled = true`. EIP allocations are consumed in order, so `allocation_ids[i]` is attached to the NAT Gateway in `availability_zones[i]`.

### With VPC Endpoints

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Endpoint example pins old release

The new VPC-endpoint example pins v1.0.0, which predates the endpoint arguments shown below it, so copying the example produces unsupported-argument errors instead of creating endpoints.

Prompt To Fix With AI
This is a comment left during a code review.
Path: networking/vpc/README.md
Line: 90

Comment:
**Endpoint example pins old release**

The new VPC-endpoint example pins `v1.0.0`, which predates the endpoint arguments shown below it, so copying the example produces unsupported-argument errors instead of creating endpoints.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@flybayer flybayer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i made s3 collapsible

@mabadir
mabadir merged commit d52db6a into main Aug 20, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants