We Migrated the DevelopersIO Platform to a "Public-Subnet-less" ECS Configuration

We Migrated the DevelopersIO Platform to a "Public-Subnet-less" ECS Configuration

We built a new ECS platform with no public subnets, using CloudFront VPC Origin and Regional NAT Gateway. Covers Graviton4 benchmarks, Spot Instances, and dev environment improvements with ECS Express Mode.
2025.12.25

This page has been translated by machine translation. View original

We have migrated the backend infrastructure of this blog (DevelopersIO) to a public-subnet-less configuration using Regional NAT Gateway and CloudFront VPC Origin, which we had been validating for some time, and have started production operation.

This article introduces the details of the network configuration that completely eliminates public subnets, the validation of adopting the ARM architecture (Fargate/Graviton), and our considerations for cost optimization.

1. Configuration Overview: Migration to a Public-Subnet-Less Setup

Based on the architecture using a public-subnet-less VPC that we validated in a previous article, we built out the production, development, and DR environments.

https://dev.classmethod.jp/articles/ecs-express-mode-public-subnet-less/

Overall Configuration

The biggest feature is that public subnets have been eliminated from the VPC. All compute resources are placed in private subnets.

Overall architecture diagram

  • Regional NAT Gateway: While supporting multi-AZ redundancy, it eliminates the need for the public subnets that a conventional NAT Gateway deployment requires.
  • ECS + Internal ELB: Containers and load balancers all run in the private area.
  • CloudFront VPC Origin: CloudFront connects to the Internal ALB, blocking direct access from the internet.

Development Environment: Using ECS Express Mode

For the development and test environments, we prioritized cost efficiency and deployment speed, and adopted ECS Express Mode.

ECS Express Mode adoption image

  • Shared ELB: We configured a single ELB to be shared across around 10 execution environments (services using Express Mode). This significantly reduces fixed costs compared with creating an ALB for each service.
  • SSL certificate behavior: HTTPS is required to use CloudFront VPC Origin, but our validation confirmed that Express Mode automatically provides a certificate for the "aws" domain. This removes the need to add DNS records (for ACM) and helps shorten the lead time for provisioning environments.

2. Performance Validation: Adopting the ARM Architecture and Introducing Graviton4

When building the production environment, we evaluated whether to adopt x86 or ARM architecture from both performance and cost perspectives.

x86 vs ARM Comparison on Fargate

First, in a Fargate environment (vCPU 1, memory 2GB, running 730 hours per month), we compared cost and response performance based on ALB access logs.

Environment Average response time Monthly cost (approx.)
x86 Fargate (On-Demand) 0.149 - 0.182 sec About $45
ARM Fargate (On-Demand) 0.163 sec About $36
ARM Fargate (Spot) --- $11.23

When using ARM Fargate Spot, the difference in response time compared with x86 On-Demand was only slight (about 0.01-0.02 seconds).
Since it turned out that costs could be reduced significantly, we decided to actively adopt Spot and the ARM architecture in the production environment.

EC2 Graviton Generation Benchmarks

Based on the above policy, we also selected the Graviton family for regular ECS (EC2 launch type) and ran performance tests on each generation (Graviton2, 3, 4).

Conditions: vCPU 1, memory 2GB, 1 instance/1 task

Instance CPU generation Average response time P90 response time Spot savings rate
m8gd.large Graviton4 0.150 sec 0.398 sec 66.95%
m7gd.large Graviton3 0.160 sec 0.422 sec 66.68%
im4gn.large Graviton2 0.193 sec 0.497 sec 77.51%

Based on the log analysis, we reached the following conclusions.

  • Adopting Graviton4 (m8gd): We confirmed that the latest generation has the lowest latency. In addition, because the price difference between m8gd (with disk) and m8g (without disk) is minimal, we mainly adopted m8gd in the production environment and configured the built-in instance store (NVMe SSD) to be mounted and used as /tmp and swap areas.
  • Not adopting Graviton2 (im4gn): Since its response time was confirmed to be inferior to the m8g and m7g generations, we decided to hold off on adopting it for now.

3. Ensuring Availability in Production: Hybrid Configuration

To balance cost reduction with availability in the production environment, we built a hybrid configuration of EC2 and Fargate.

Measures against capacity shortages:
To prepare for the risk of Spot Instance interruptions, we have applied the following diversification settings.

  • Multiple AZs: Task launches are allowed in all 3 AZs.
  • Diversified instance types: Multiple families such as m7gd, m8gd, and r8gd are configured as candidates.

4. Validating Network Cost Optimization

Adopting a Dedicated ELB

In the production environment, we deployed a dedicated ELB (Internal ALB). Because an Internal ALB does not incur IPv4 charges (Public IPv4 address usage fees), we were able to avoid additional fixed costs even with a highly available 3-AZ configuration. This also makes it easier to separate access logs and metrics, improving the efficiency of incident investigation.

NAT Gateway vs VPC Endpoints

As the communication path to AWS services such as ECR, we compared using Interface VPC Endpoints (VPCE) with using a NAT Gateway.

  1. In the case of VPCE:
  • 3 services × 3 AZs × $75-$90/month in additional fixed costs
  1. In the case of NAT Gateway:
  • Traffic for ECR and similar services is expected to be several tens of GB per month. Our estimate showed that data processing charges would also be just a few dollars per month.

At this traffic scale, we concluded that going through a NAT Gateway is overwhelmingly cheaper than introducing VPCE. We have also designed the configuration with future IPv6 DualStack support in mind, which would allow the use of an Egress-Only Internet Gateway (reducing NAT Gateway data transfer costs).

5. Operational Improvements and DR Strategy

Shortening ECS Express Mode Deployments

We observed that deployments with ECS Express Mode take a long time to complete under the default settings. We manually changed the CodeDeploy settings and verified the result.

  • Canary bake time: 3 minutes → 0 minutes
  • Deployment bake time: 3 minutes → 0 minutes

We confirmed that this configuration change can shorten deployment time by up to 6 minutes.

https://dev.classmethod.jp/articles/ecs-experss-reduce-deployment-time/

DR Environment: App Runner Returns

App Runner had been used for frontend operation since 2023, but due to the difficulty of obtaining access logs and WAF costs, we decided to remove it from the main environment. It is now running as a "DR (standby) environment in the Virginia region" with the following configuration.

DR image

  • App Runner: Maintains a standby environment for around $10 per month.
  • ECR Replication: Automates image synchronization from Tokyo to Virginia.
  • StepFunctions: Achieves Lambda-less App Runner deployment through SDK integration.
  • CloudFront Failover: Automatic switchover when 5xx errors are detected.

As a BCP measure, it delivers extremely high cost performance.

Summary

We migrated to the new infrastructure utilizing Regional NAT Gateway and ECS Express Mode, and confirmed the following results.

  • Configuration: We achieved a secure, public-subnet-less VPC configuration in the production environment.
  • Performance: We adopted the latest Graviton4 (m8gd), achieving both cost efficiency and high performance with the ARM architecture.
  • Cost: By using Spot Instances and minimizing unnecessary VPCE and IPv4 usage, we kept cost increases to a minimum even in an environment using a VPC and ECS.

We look forward to the expanding scope of IPv6 support in AWS, which would help reduce NAT Gateway costs and, ultimately, enable VPC network usage without NAT Gateways or VPC endpoints.

Share this article

AWSのお困り事はクラスメソッドへ