Search code examples
amazon-s3terraformlocalstack

Terraform appending S3 bucket name to endpoint URL?


I have an extremely simple S3 set up in localstack defined via terraform:

provider "aws" {
  region                  = "us-east-1"  # Change to your desired region
  access_key              = "test"       # Access key for LocalStack
  secret_key              = "test"       # Secret key for LocalStack
  skip_credentials_validation = true
  skip_requesting_account_id = true
  skip_metadata_api_check     = true

  endpoints {
    s3 = "http://locahost:4566"
  }
}
resource "aws_s3_bucket" "images_bucket" {
  bucket = "images-bucket"
  acl    = "private"

  tags = {
    Environment = "Development"
  }
}

I know that the S3 service is available and working since I can call awslocal s3api create-bucket --bucket sample-bucket via terminal. However, when I run terraform apply and say 'yes', it tells me its 'creating' the S3 bucket for 20 seconds or so and then throws:

 Error: Error creating S3 bucket: RequestError: send request failed
│ caused by: Put "http://images-bucket.localhost:4566/": dial tcp: lookup images-bucket.127.0.0.1 on [2603:7000:4df0:8610::1]:53: no such host
│ 
│   with module.S3_module.aws_s3_bucket.images_bucket,
│   on S3/main.tf line 1, in resource "aws_s3_bucket" "images_bucket":
│    1: resource "aws_s3_bucket" "images_bucket" {

It looks to me like the terraform is somehow appending the bucket name to the front of defined endpoint. I am not positive this is the cause for the error but it seems likely given the terraform definition is so basic. Why is it adding the bucket name to the front of the endpoint? How can I prevent this?

I can see in this other post that others have had issues with this. The answer there suggests adding (terraform equivalent) s3_force_path_style = true to the provider definition. This still throws the same error, but now with the path as http://localhost:4566/images-bucket.

To be clear I also have a litany of other resources defined at this endpoint and they work fine. Docker ps confirms the port is correctly mapped.


Solution

  • In this case, you can use the S3 endpoint as:

    s3 = "http://s3.localhost.localstack.cloud:4566"
    

    After running terraform apply, you should see the following output:

    Plan: 1 to add, 0 to change, 0 to destroy.
    aws_s3_bucket.images_bucket: Creating...
    aws_s3_bucket.images_bucket: Creation complete after 2s [id=images-bucket]
    

    In LocalStack, the way S3 works is different from other services, especially in how its endpoints are set up. You can find this in the S3 docs: https://docs.localstack.cloud/user-guide/aws/s3/