Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions src/content/docs/aws/connecting/aws-sdks/php.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,28 @@ Here is an example of how to create an `S3Client` with the endpoint set to Local
use Aws\S3\S3Client;
use Aws\Exception\AwsException;

// Configuring S3 Client
// Configuring S3 Client with virtual-hosted-style addressing (recommended)
$s3 = new Aws\S3\S3Client([
'version' => '2006-03-01',
'region' => 'us-east-1',
// Enable 'use_path_style_endpoint' => true, if bucket name is non DNS compliant
'use_path_style_endpoint' => true,
'endpoint' => 'http://s3.localhost.localstack.cloud:4566',
]);
```

This configuration uses virtual-hosted-style addressing, which AWS recommends and some regions require.

If you need to use path-style addressing (for non-DNS-compliant bucket names or other specific requirements), enable it explicitly:

```php showshowLineNumbers
// Only use path-style if you have a specific requirement for it
$s3 = new Aws\S3\S3Client([
'version' => '2006-03-01',
'region' => 'us-east-1',
'use_path_style_endpoint' => true,
'endpoint' => 'http://localhost:4566', // Use non-S3-prefixed endpoint with path-style
]);
```

A full example can be found [in our samples repository](https://github.com/localstack/localstack-aws-sdk-examples/tree/main/php).

## Resources
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,6 @@ provider "aws" {
secret_key = "test"
region = "us-east-1"


# only required for non virtual hosted-style endpoint use case.
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs#s3_use_path_style
s3_use_path_style = true
skip_credentials_validation = true
skip_metadata_api_check = true
}
Expand All @@ -140,18 +136,34 @@ provider "aws" {
### Services

Furthermore, it's necessary to configure the individual services to use LocalStack.
For S3, this configuration resembles the following snippet, where we've chosen to use the virtual hosted-style endpoint:

#### Using AWS_ENDPOINT_URL_S3 (Recommended for S3)

With terraform-provider-aws version 5.x and later, you can use the `AWS_ENDPOINT_URL_S3` environment variable instead of configuring the endpoint in your Terraform code:

```bash
export AWS_ENDPOINT_URL_S3=http://s3.localhost.localstack.cloud:4566
```

This allows your Terraform configuration to work unchanged against both LocalStack and real AWS.
No `endpoints` block is needed for S3, and virtual-hosted-style addressing is used by default.

#### Configuring Endpoints in Terraform

Alternatively, you can configure service endpoints directly in your provider block.
For S3, use the virtual hosted-style endpoint:

```hcl showshowLineNumbers
endpoints {
s3 = "http://s3.localhost.localstack.cloud:4566"
s3 = "http://s3.localhost.localstack.cloud:4566"
}
```

:::note
The S3 endpoint uses the `s3.localhost.localstack.cloud` hostname to support virtual-hosted-style addressing, which AWS recommends and some regions require.

If there are any difficulties resolving this DNS record, you can utilize `http://localhost:4566` as a fallback option in combination with setting `s3_use_path_style = true` in the provider.
It's worth noting that the S3 service endpoint differs slightly from the other service endpoints due to AWS deprecating path-style based access for hosting buckets.
If you cannot resolve this DNS record, you can use `http://localhost:4566` as a fallback and enable path-style addressing by adding `s3_use_path_style = true` to the provider configuration.
Only use path-style if you have a specific requirement for it.
:::

### Final Configuration
Expand All @@ -165,12 +177,11 @@ provider "aws" {
secret_key = "mock_secret_key"
region = "us-east-1"

s3_use_path_style = true
skip_credentials_validation = true
skip_metadata_api_check = true

endpoints {
s3 = "http://s3.localhost.localstack.cloud:4566"
s3 = "http://s3.localhost.localstack.cloud:4566"
}
}

Expand All @@ -179,6 +190,16 @@ resource "aws_s3_bucket" "test-bucket" {
}
```

:::tip
With terraform-provider-aws >= 5.x, you can simplify this further by removing the `endpoints` block and using the environment variable instead:

```bash
export AWS_ENDPOINT_URL_S3=http://s3.localhost.localstack.cloud:4566
```

Then your provider configuration only needs the credentials and skip parameters.
:::

### Endpoint Configuration

Here's a configuration example with additional service endpoints.
Expand All @@ -190,7 +211,6 @@ provider "aws" {
access_key = "test"
secret_key = "test"
region = "us-east-1"
s3_use_path_style = true
skip_credentials_validation = true
skip_metadata_api_check = true

Expand Down Expand Up @@ -222,6 +242,11 @@ provider "aws" {
}
```

:::note
The S3 endpoint uses `s3.localhost.localstack.cloud` to support virtual-hosted-style addressing (AWS recommended).
If you need to use path-style addressing instead, change the S3 endpoint to `http://localhost:4566` and add `s3_use_path_style = true` to the provider block.
:::

:::note
To heuristically detect whether your Terraform configuration should be deployed against LocalStack, you can use the following snippet:

Expand Down Expand Up @@ -270,28 +295,28 @@ provider "aws" {
access_key = "test"
secret_key = "test"
region = "us-east-1"
s3_use_path_style = true
skip_credentials_validation = true
skip_metadata_api_check = true

endpoints {
apigateway = "http://localhost:4566"
dynamodb = "http://localhost:4566"
iam = "http://localhost:4566"
kinesis = "http://localhost:4566"
lambda = "http://localhost:4566"
s3 = "http://s3.localhost.localstack.cloud:4566"
ses = "http://localhost:4566"
sns = "http://localhost:4566"
sqs = "http://localhost:4566"
sts = "http://localhost:4566"
apigateway = "http://localhost:4566"
dynamodb = "http://localhost:4566"
iam = "http://localhost:4566"
kinesis = "http://localhost:4566"
lambda = "http://localhost:4566"
s3 = "http://s3.localhost.localstack.cloud:4566"
ses = "http://localhost:4566"
sns = "http://localhost:4566"
sqs = "http://localhost:4566"
sts = "http://localhost:4566"
}
}
EOF
}
```

You can add more service endpoints to the above configuration as needed, and point them to LocalStack (`http://localhost:4566`).
Note that the S3 endpoint uses `s3.localhost.localstack.cloud` to support virtual-hosted-style addressing.

## Examples

Expand Down
83 changes: 64 additions & 19 deletions src/content/docs/aws/services/s3.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -122,37 +122,82 @@ awslocal s3 presign s3://sample-bucket/image.jpg
You will see a generated pre-signed URL for your S3 object.
You can use [curl](https://curl.se/) or [`wget`](https://www.gnu.org/software/wget/) to retrieve the S3 object using the pre-signed URL.

## Path-Style and Virtual Hosted-Style Requests
## Configuring S3 Endpoint

Similar to AWS, LocalStack categorizes requests as either [Path style or Virtual-Hosted style](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html) based on the Host header of the request.
The following example illustrates this distinction:
LocalStack supports both [Virtual-Hosted style and Path style](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html) S3 requests.
AWS recommends Virtual-Hosted style addressing, and some AWS regions do not support path-style requests at all.
LocalStack follows this recommendation: **Virtual-Hosted style is the default and recommended approach**.

### Recommended: Using AWS_ENDPOINT_URL_S3

The simplest way to configure your application to use LocalStack's S3 endpoint is with the `AWS_ENDPOINT_URL_S3` environment variable.
This approach works with modern AWS SDKs and tools without requiring code changes:

```bash
export AWS_ENDPOINT_URL_S3=http://s3.localhost.localstack.cloud:4566
```

This environment variable is supported by:
- **AWS CLI v2**: All `aws s3` and `aws s3api` commands automatically use this endpoint
- **boto3** (Python SDK) with botocore >= 1.29: `boto3.client("s3")` resolves the endpoint automatically
- **Terraform** with terraform-provider-aws >= 5.x: No `endpoints {}` block needed in your configuration

With this variable set, your application code remains unchanged and can run against both LocalStack and real AWS by simply changing the environment.

### Virtual-Hosted Style Requests

A **Virtual-Hosted style** request includes the bucket name as part of the `Host` header.
For LocalStack to parse the bucket name correctly, your endpoint must be prefixed with `s3.`, like `s3.localhost.localstack.cloud`:

```bash
http://<bucket-name>.s3.<region>.localhost.localstack.cloud:4566/<key-name> # host-style request
http://<bucket-name>.s3.localhost.localstack.cloud:4566/<key-name> # host-style request, region is not mandatory in LocalStack
http://s3.<region>.localhost.localstack.cloud:4566/<bucket-name>/<key-name> # path-style request
http://localhost:4566/<bucket-name>/<key-name> # path-style request
http://<bucket-name>.s3.localhost.localstack.cloud:4566/<key-name>
```

A **Virtual-Hosted style** request will have the `bucket` as part of the `Host` header of your request.
In order for LocalStack to be able to parse the bucket name from your request, your endpoint needs to be prefixed with `s3.`, like `s3.localhost.localstack.cloud`.
This is the format that `AWS_ENDPOINT_URL_S3` uses, and it's what most modern AWS SDKs use by default.

If your endpoint cannot be prefixed with `s3.`, you should configure your SDK to use **Path style** request instead, and make the bucket part of the path.
### Path Style Requests (Fallback)

By default, most SDKs will try to use **Virtual-Hosted style** requests and prepend your endpoint with the bucket name.
However, if the endpoint is not prefixed by `s3.`, LocalStack will not be able to understand the request and it will most likely result in an error.
**Path style** requests include the bucket as part of the URL path instead of the hostname:

You can either change the endpoint to an S3-specific one, or configure your SDK to use **Path style** requests instead.
Check out our [SDK documentation](/aws/customization/integrations/localstack-sdks/) to learn how you can configure AWS SDKs to access LocalStack and S3.
```bash
http://localhost:4566/<bucket-name>/<key-name>
```

You should only use path-style requests if you have a specific reason:
- Your bucket names are not DNS-compliant (contain underscores, uppercase letters, etc.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

uppercase letters are not supported in LocalStack, this was a very old feature of AWS that has been removed ages ago

- You're using an older SDK or tool that doesn't support virtual-hosted style
- You have specific networking constraints that prevent using wildcard DNS

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

one of the big case we have in Docker compose: as you need to specify the service name, you cannot use wildcard DNS there, and it was one of the biggest source of incoming reports from users.


To use path-style requests with AWS SDKs, you must explicitly enable it and use a non-S3-prefixed endpoint:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

you can use the prefixed endpoint with path style, it's even better? Not sure why this is specified


:::tip
While using [AWS SDKs](https://aws.amazon.com/developer/tools/#SDKs), you would need to configure the `ForcePathStyle` parameter to `true` in the S3 client configuration to use **Path style** requests.
If you want to use virtual host addressing of buckets, you can remove `ForcePathStyle` from the configuration.
The `ForcePathStyle` parameter name can vary between SDK and languages, please check our [SDK documentation](/aws/connecting/aws-sdks/)
To enable path-style requests in [AWS SDKs](https://aws.amazon.com/developer/tools/#SDKs), set the `ForcePathStyle` parameter to `true` in your S3 client configuration.
The parameter name varies by SDK:
- Python (boto3): `s3={'addressing_style': 'path'}` in the Session config, or `S3ForcePathStyle=true` in the Config
- JavaScript: `forcePathStyle: true`
- Go: `WithS3ForcePathStyle(true)`
- Terraform: `s3_use_path_style = true`
- PHP: `use_path_style_endpoint => true`

Check our [SDK documentation](/aws/connecting/aws-sdks/) for language-specific examples.
:::

If your endpoint is not prefixed with `s3.`, all requests are treated as **Path style** requests.
Using the `s3.localhost.localstack.cloud` endpoint URL is recommended for all requests aimed at S3.
### Endpoint URL Formats

LocalStack recognizes the following endpoint formats:

```bash
# Virtual-Hosted style (recommended)
http://<bucket-name>.s3.localhost.localstack.cloud:4566/<key-name>
http://<bucket-name>.s3.<region>.localhost.localstack.cloud:4566/<key-name>

# Path style (fallback)
http://s3.localhost.localstack.cloud:4566/<bucket-name>/<key-name>
http://s3.<region>.localhost.localstack.cloud:4566/<bucket-name>/<key-name>
http://localhost:4566/<bucket-name>/<key-name>
```

For detailed configuration instructions for specific SDKs and tools, see our [SDK documentation](/aws/customization/integrations/localstack-sdks/) and [Infrastructure as Code guides](/aws/connecting/infrastructure-as-code/).

## Configuring Cross-Origin Resource Sharing on S3

Expand Down
Loading