Terraform Issues

No valid credential sources found

Symptom: terraform plan or terraform apply fails with:

Error: no valid credential sources for S3 Backend found

or

Error: configuring Terraform AWS Provider: no valid credential sources found

Solution: Set the required environment variables before running Terraform:

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

Alternatively, configure credentials in the provider block:

provider "aws" {
  access_key = "AKIAIOSFODNN7EXAMPLE"
  secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
  region     = "us-east-1"
}

InvalidClientTokenId

Symptom: Terraform operations fail with InvalidClientTokenId errors.

Cause: Simfra validates SigV4 signatures against known access keys. The access key in your credentials must exist in Simfra.

Solutions:

  1. Use the default root credentials:

    export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
    export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
    
  2. If you created a custom IAM user, use that user's access key:

    aws iam create-access-key --user-name myuser
    
  3. If you created a custom account via the admin API, use the root credentials returned in the creation response.


S3 backend not working

Symptom: Terraform's S3 state backend fails to connect or returns errors.

Solutions:

  1. Use local backend instead. The simplest approach for local development is to skip S3 state entirely:

    terraform {
      backend "local" {}
    }
    
  2. If you must use the S3 backend, configure it for path-style and point it at Simfra. With Terraform 1.6+:

    terraform {
      backend "s3" {
        bucket = "my-tf-state"
        key    = "terraform.tfstate"
        region = "us-east-1"
    
        use_path_style = true
      }
    }
    

    Note: the S3 backend requires use_path_style = true because it does not read AWS_S3_USE_PATH_STYLE. The AWS_ENDPOINT_URL environment variable routes the backend to Simfra automatically.

  3. Create the bucket first - the S3 backend expects the bucket to already exist:

    aws s3 mb s3://my-tf-state --endpoint-url http://localhost:4599
    

ResourceNotFoundException

Symptom: Terraform fails with ResourceNotFoundException or 404 Not Found when referencing a resource.

Cause: The resource does not exist yet. This commonly happens when:

  1. Missing bootstrap - Your Terraform config references default VPC, subnets, or other infrastructure that has not been created. Bootstrap first:

    export SIMFRA_BOOTSTRAP=standard
    

    Or bootstrap via the admin API:

    curl -X POST http://localhost:4599/_simfra/accounts \
      -d '{"accountId": "000000000000", "bootstrap": "standard", "region": "us-east-1"}'
    
  2. Dependency ordering - Terraform may try to read a data source before the resource is created. Use depends_on to enforce ordering.

  3. Different account or region - Verify your credentials correspond to the account where the resource was created, and the region matches.


Provider version

Symptom: Terraform does not recognize AWS_ENDPOINT_URL or the endpoint configuration does not work.

Solution: Use AWS provider version 5.0 or later. The AWS_ENDPOINT_URL environment variable (which routes all services to a single endpoint) requires provider >= 5.0.

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 5.0"
    }
  }
}

With older providers, you must configure per-service endpoints in the endpoints block, which is verbose and error-prone.


Missing endpoints block

Symptom: You expect to need a per-service endpoints block in the provider configuration but it does not seem to be required.

Explanation: With AWS provider >= 5.0, the AWS_ENDPOINT_URL environment variable routes all AWS services to a single endpoint. No endpoints block is needed.

export AWS_ENDPOINT_URL=http://localhost:4599

Simfra routes requests to the correct service using the SigV4 signature, Host header, and X-Amz-Target header - just like real AWS. A single endpoint URL handles all 88+ services.

The endpoints {} block is not needed and should not be used. AWS_ENDPOINT_URL routes all services to Simfra automatically.