SDK Configuration
All modern AWS SDKs support the AWS_ENDPOINT_URL environment variable. When running inside Simfra containers (Lambda, ECS, EC2), this is injected automatically. For host applications, set it manually.
Prerequisites
- Simfra running on
localhost:4599(see Installation) - AWS credentials configured (see Credentials)
Environment Variables
export AWS_ENDPOINT_URL=http://localhost:4599
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
export AWS_DEFAULT_REGION=us-east-1
With these variables set, SDK code in any language works without modification. This page also shows explicit endpoint configuration for cases where environment variables are not an option.
Go (aws-sdk-go-v2)
Automatic (environment variable)
package main
import (
"context"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/aws/aws-sdk-go-v2/service/s3"
)
func main() {
ctx := context.Background()
// Reads AWS_ENDPOINT_URL, AWS_REGION, and credentials from environment
cfg, err := config.LoadDefaultConfig(ctx)
if err != nil {
panic(err)
}
client := s3.NewFromConfig(cfg)
out, err := client.ListBuckets(ctx, &s3.ListBucketsInput{})
if err != nil {
panic(err)
}
for _, b := range out.Buckets {
println(*b.Name)
}
}
Explicit endpoint override
cfg, _ := config.LoadDefaultConfig(ctx,
config.WithRegion("us-east-1"),
)
client := s3.NewFromConfig(cfg, func(o *s3.Options) {
o.BaseEndpoint = aws.String("http://localhost:4599")
o.UsePathStyle = true
})
Per-client endpoint overrides are useful when you need different clients to point at different targets (e.g., one at Simfra, one at real AWS).
Python (boto3)
Automatic (environment variable)
AWS_ENDPOINT_URL is supported in boto3 >= 1.28.57 (September 2023):
import boto3
# Reads AWS_ENDPOINT_URL automatically
s3 = boto3.client('s3')
response = s3.list_buckets()
for bucket in response['Buckets']:
print(bucket['Name'])
Explicit endpoint override
import boto3
s3 = boto3.client(
's3',
endpoint_url='http://localhost:4599',
region_name='us-east-1',
aws_access_key_id='AKIAIOSFODNN7EXAMPLE',
aws_secret_access_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
)
dynamodb = boto3.resource(
'dynamodb',
endpoint_url='http://localhost:4599',
region_name='us-east-1'
)
boto3 session
session = boto3.Session(
region_name='us-east-1',
aws_access_key_id='AKIAIOSFODNN7EXAMPLE',
aws_secret_access_key='wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
)
# All clients from this session use the same credentials
s3 = session.client('s3', endpoint_url='http://localhost:4599')
sqs = session.client('sqs', endpoint_url='http://localhost:4599')
JavaScript / TypeScript (AWS SDK v3)
Automatic (environment variable)
AWS_ENDPOINT_URL is supported in AWS SDK for JavaScript v3 >= 3.451.0:
import { S3Client, ListBucketsCommand } from '@aws-sdk/client-s3';
// Reads AWS_ENDPOINT_URL automatically
const client = new S3Client({ region: 'us-east-1' });
const { Buckets } = await client.send(new ListBucketsCommand({}));
Buckets?.forEach(b => console.log(b.Name));
Explicit endpoint override
import { S3Client, ListBucketsCommand } from '@aws-sdk/client-s3';
const client = new S3Client({
endpoint: 'http://localhost:4599',
region: 'us-east-1',
credentials: {
accessKeyId: 'AKIAIOSFODNN7EXAMPLE',
secretAccessKey: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
},
forcePathStyle: true // Required for S3
});
DynamoDB example
import { DynamoDBClient, PutItemCommand } from '@aws-sdk/client-dynamodb';
const dynamodb = new DynamoDBClient({ region: 'us-east-1' });
await dynamodb.send(new PutItemCommand({
TableName: 'my-table',
Item: {
id: { S: '123' },
name: { S: 'test' }
}
}));
Java (AWS SDK v2)
Explicit endpoint override
The Java SDK v2 does not read AWS_ENDPOINT_URL automatically. Configure the endpoint explicitly:
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import java.net.URI;
public class SimfraExample {
public static void main(String[] args) {
S3Client s3 = S3Client.builder()
.endpointOverride(URI.create("http://localhost:4599"))
.region(Region.US_EAST_1)
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create(
"AKIAIOSFODNN7EXAMPLE",
"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
)
))
.forcePathStyle(true) // Required for S3
.build();
s3.listBuckets().buckets().forEach(
b -> System.out.println(b.name())
);
}
}
DynamoDB example
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.*;
DynamoDbClient dynamodb = DynamoDbClient.builder()
.endpointOverride(URI.create("http://localhost:4599"))
.region(Region.US_EAST_1)
.build();
dynamodb.putItem(PutItemRequest.builder()
.tableName("my-table")
.item(Map.of(
"id", AttributeValue.fromS("123"),
"name", AttributeValue.fromS("test")
))
.build());
Reusable configuration helper
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.sqs.SqsClient;
public class SimfraClients {
private static final URI ENDPOINT = URI.create(
System.getenv().getOrDefault("AWS_ENDPOINT_URL", "http://localhost:4599")
);
public static S3Client s3() {
return S3Client.builder()
.endpointOverride(ENDPOINT)
.region(Region.US_EAST_1)
.forcePathStyle(true)
.build();
}
public static SqsClient sqs() {
return SqsClient.builder()
.endpointOverride(ENDPOINT)
.region(Region.US_EAST_1)
.build();
}
}
.NET (AWS SDK for .NET)
using Amazon;
using Amazon.S3;
using Amazon.Runtime;
var credentials = new BasicAWSCredentials(
"AKIAIOSFODNN7EXAMPLE",
"wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
);
var config = new AmazonS3Config
{
ServiceURL = "http://localhost:4599",
ForcePathStyle = true,
AuthenticationRegion = "us-east-1"
};
var s3 = new AmazonS3Client(credentials, config);
var response = await s3.ListBucketsAsync();
foreach (var bucket in response.Buckets)
{
Console.WriteLine(bucket.BucketName);
}
Ruby (AWS SDK v3)
require 'aws-sdk-s3'
# Reads AWS_ENDPOINT_URL automatically (aws-sdk-core >= 3.186.0)
s3 = Aws::S3::Client.new(region: 'us-east-1')
# Or explicit:
s3 = Aws::S3::Client.new(
endpoint: 'http://localhost:4599',
region: 'us-east-1',
access_key_id: 'AKIAIOSFODNN7EXAMPLE',
secret_access_key: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY',
force_path_style: true
)
s3.list_buckets.buckets.each { |b| puts b.name }
S3 Path Style
Simfra runs on localhost, so S3 virtual-hosted-style addressing (bucket.s3.amazonaws.com) does not work. All S3 SDK clients must use path-style addressing:
| Language | Setting |
|---|---|
| Go | o.UsePathStyle = true |
| Python | Handled automatically by endpoint_url |
| JavaScript | forcePathStyle: true |
| Java | .forcePathStyle(true) |
| .NET | ForcePathStyle = true |
| Ruby | force_path_style: true |
When running inside Simfra containers, path-style is configured automatically via AWS_S3_US_EAST_1_REGIONAL_ENDPOINT=regional.
TLS / HTTPS
Simfra serves HTTP (not HTTPS) by default. SDK clients connecting from the host use http://localhost:4599. No TLS certificates are needed.
Inside Docker containers, connections to Simfra also use HTTP. The AWS_ENDPOINT_URL injected by Simfra always uses the http:// scheme.
Next Steps
- Endpoint Discovery - how Lambda, ECS, and EC2 workloads discover the Simfra endpoint
- Writing Lambda Functions - building Lambda functions that run in Simfra
- CA Trust Setup - import the Simfra root CA for HTTPS access to Docker-backed services