When Localhost Isn't Local: Fixing Terraform Apply Failures in LocalStack Docker Setups
When Localhost Isn't Local: Fixing Terraform Apply Failures in LocalStack Docker Setups
Problem
or
Clarifying the Issue
The tflocal script uses the Terraform Override mechanism and creates a temporary file localstack_providers_override.tf to configure the endpoints for the AWS provider section. The endpoints for all services are configured to point to the LocalStack API (http://localhost:4566 by default).
By default, tflocal configures S3 to use S3_HOSTNAME: special hostname to be used to connect to LocalStack S3 (default: s3.localhost.localstack.cloud).
The core issue: inside the Terraform container, localhost refers to that container itself, not the localstack service running in a separate container. When tflocal generates endpoints like http://s3.localhost.localstack.cloud:4566, Terraform tries to connect to 127.0.0.1:4566 within its own container, which leads nowhere.
The tflocal script uses the Terraform Override mechanism and creates a temporary file localstack_providers_override.tf to configure the endpoints for the AWS provider section. The endpoints for all services are configured to point to the LocalStack API (http://localhost:4566 by default).
By default, tflocal configures S3 to use S3_HOSTNAME: special hostname to be used to connect to LocalStack S3 (default: s3.localhost.localstack.cloud).
The core issue: inside the Terraform container, localhost refers to that container itself, not the localstack service running in a separate container. When tflocal generates endpoints like http://s3.localhost.localstack.cloud:4566, Terraform tries to connect to 127.0.0.1:4566 within its own container, which leads nowhere.
Why It Matters
This is a classic container networking problem that affects any multi-container setup using tflocal. The issue is particularly confusing because:
- terraform init often succeeds (it downloads providers and modules)
- terraform apply fails during actual AWS API calls (like S3 bucket creation)
- The error messages point to localhost URLs that work fine when running Terraform on the host machine
Key Terms
- LocalStack – A fully functional local AWS cloud stack for development and testing
- tflocal – A small wrapper script to run Terraform against LocalStack that automatically configures service endpoints
- Docker Compose network – A virtual network where containers can reach each other via service names
- localhost in containers – Always refers only to the container itself, not the host or other containers
- Provider Override – Terraform mechanism that tflocal uses to create a temporary localstack_providers_override.tf file
Steps at a Glance
- Choose Your Fix Strategy
- Verify Network Configuration
- Test Container Connectivity
- Clean and Apply
- Verify Success
Detailed Steps
Step 1: Choose Your Fix Strategy
You have two main options to resolve the container networking issue:
Option A: Override S3 Endpoint (Recommended)
Add an explicit S3 endpoint override in your Terraform configuration:
This overrides tflocal's automatic localhost-based endpoint configuration.
Option B: Configure S3_HOSTNAME Environment Variable
Set the S3_HOSTNAME environment variable in your Terraform container to use the LocalStack service name:
Step 2: Verify Network Configuration
Ensure both containers are on the same Docker network. Your setup should look like:
Step 3: Test Container Connectivity
Verify that your Terraform container can reach LocalStack:
You should see a JSON response confirming LocalStack services are ready.
Step 4: Clean and Apply
Remove any existing override files and apply your infrastructure:
Step 5: Verify Success
You can verify your S3 bucket was created by checking the LocalStack endpoint or using awslocal commands.
Conclusion
When containerizing Terraform with tflocal, the key insight is that Docker container networking requires service names, not localhost. While tflocal automatically configures endpoints to point to http://localhost:4566 by default, this only works when running on the host machine.
For container-to-container communication, you must either override the S3 endpoint to use your LocalStack service name or configure the S3_HOSTNAME environment variable. Both approaches ensure that Terraform connects to the correct LocalStack instance instead of trying to reach a non-existent localhost service.
Remember: in Docker networks, service names are your DNS, not localhost addresses. Once you fix the networking, tflocal works exactly as expected, giving you the full power of LocalStack for local AWS development without the networking headaches.
Step 1: Choose Your Fix Strategy
You have two main options to resolve the container networking issue:
Option A: Override S3 Endpoint (Recommended)
Add an explicit S3 endpoint override in your Terraform configuration:
This overrides tflocal's automatic localhost-based endpoint configuration.
Option B: Configure S3_HOSTNAME Environment Variable
Set the S3_HOSTNAME environment variable in your Terraform container to use the LocalStack service name:
Step 2: Verify Network Configuration
Ensure both containers are on the same Docker network. Your setup should look like:
Step 3: Test Container Connectivity
Verify that your Terraform container can reach LocalStack:
You should see a JSON response confirming LocalStack services are ready.
Step 4: Clean and Apply
Remove any existing override files and apply your infrastructure:
Step 5: Verify Success
You can verify your S3 bucket was created by checking the LocalStack endpoint or using awslocal commands.
Conclusion
When containerizing Terraform with tflocal, the key insight is that Docker container networking requires service names, not localhost. While tflocal automatically configures endpoints to point to http://localhost:4566 by default, this only works when running on the host machine.
For container-to-container communication, you must either override the S3 endpoint to use your LocalStack service name or configure the S3_HOSTNAME environment variable. Both approaches ensure that Terraform connects to the correct LocalStack instance instead of trying to reach a non-existent localhost service.
Remember: in Docker networks, service names are your DNS, not localhost addresses. Once you fix the networking, tflocal works exactly as expected, giving you the full power of LocalStack for local AWS development without the networking headaches.
Aaron Rose is a software engineer and technology writer at tech-reader.blog.
Comments
Post a Comment