Context

In one of my homelab servers I make a heavy use of Docker containers (yes, plain Docker) to provide different tools and applications. At this time, I was looking for a way of moving Terraform state files from the cloud to my home controlled infrastructure to reduce costs. I already knew that there were different implementations of the AWS S3 object storage system, Cepth and MinIO, so I decided to test MinIO.

MinIO Deployment

As usual, I put the MinIO deployment into a docker-compose.yaml like the one below which makes MinIO available considering:

  • It’s behind Traefik proxy.
  • proxy network is Traefik network.
  • I pass MINIO_BROWSER_REDIRECT_URL so that when reaching s3.domain.local with a browser it redirects to the MinIO management console.
version: '3'

services:
  minio:
    image: minio/minio:<tag>
    command:
      - server
      - /data
      - --console-address
      - ":9001"
    environment:
      - MINIO_BROWSER_REDIRECT_URL=http://s3-console.domain.local
    networks:
      - proxy
    volumes:
      - </host/path>:/data
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.minio.entrypoints=http"
      - "traefik.http.routers.minio.service=minio"
      - "traefik.http.routers.minio.rule=Host(`s3.domain.local`)"
      - "traefik.http.services.minio.loadbalancer.server.port=9000"
      - "traefik.http.routers.minio-console.service=minio-console"
      - "traefik.http.routers.minio-console.rule=Host(`s3-console.domain.local`)"
      - "traefik.http.services.minio-console.loadbalancer.server.port=9001"

networks:
  proxy:
    external: true

Once the Docker resources are created (container running), you can access the Management console (s3.domain.local or s3-console.domain.local) with the default admin credentials minioadmin:minioadmin or use the MinIO CLI

S3 Bucket Creation

Once logged into the MinIO management console, I performed the following actions:

  • From the Buckets section, I created a bucket named tfstate.
  • From the Identity section, I created a Service Accounts, noting down the access and secret keys.

Terraform Backend configuration

Finally, to make use of the S3 bucket as backend for a terraform project, you configure Terraform like the following example (recently updated for Terraform 1.6.6):

terraform {
    backend "s3" {
        bucket = "tfstate"                  # Name of the S3 bucket
        endpoints = {
            s3 = "http://s3.domain.local"   # Minio endpoint
        }
        key = "project-name.tfstate"        # Name of the tfstate file

        access_key="xxxxxxxxxxxx"           # Access and secret keys
        secret_key="xxxxxxxxxxxxxxxxxxxxxx"

        region = "main"                     # Region validation will be skipped
        skip_credentials_validation = true  # Skip AWS related checks and validations
        skip_requesting_account_id = true
        skip_metadata_api_check = true
        skip_region_validation = true
        use_path_style = true             # Enable path-style S3 URLs (https://<HOST>/<BUCKET> https://developer.hashicorp.com/terraform/language/settings/backends/s3#use_path_style
    }
}

More details can be found in the official Terraform S3 Backend documentation.