Selfhosted S3 Terraform Backend using MinIO
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 reachings3.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.