Skip to content

Instantly share code, notes, and snippets.

@stefan-matic
Last active October 30, 2025 21:12
Show Gist options
  • Save stefan-matic/fb0edd37df419420c6360a1993ccbd5f to your computer and use it in GitHub Desktop.
Save stefan-matic/fb0edd37df419420c6360a1993ccbd5f to your computer and use it in GitHub Desktop.
Quick and easy script to create an S3 bucket for the Terraform S3 backend (DynamoDB not needed anymore)
#!/usr/bin/env bash
set -euo pipefail
# Configuration - Update these variables:
# Make sure PROJECT is unique since S3 bucket names must be globally unique
PROJECT="${PROJECT:-YOUR_PROJECT}"
AWS_REGION="${AWS_REGION:-YOUR_REGION}"
BUCKET="${PROJECT}-terraform-state-files"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log() {
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] $1${NC}"
}
warn() {
echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING: $1${NC}"
}
error() {
echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR: $1${NC}"
exit 1
}
validate_config() {
if [[ "${PROJECT}" == "YOUR_PROJECT" ]]; then
error "Please set PROJECT environment variable or update the script"
fi
if [[ "${AWS_REGION}" == "YOUR_REGION" ]]; then
error "Please set AWS_REGION environment variable or update the script"
fi
if ! aws sts get-caller-identity >/dev/null 2>&1; then
error "AWS credentials not configured or invalid"
fi
log "Configuration validated: PROJECT=${PROJECT}, AWS_REGION=${AWS_REGION}"
}
create_terraform_s3_bucket() {
log "Creating S3 bucket: ${BUCKET}"
# Check if bucket already exists
if aws s3api head-bucket --bucket "${BUCKET}" 2>/dev/null; then
warn "Bucket ${BUCKET} already exists, skipping creation"
return 0
fi
# Create bucket (handle us-east-1 special case)
if [[ "${AWS_REGION}" == "us-east-1" ]]; then
aws s3api create-bucket \
--region "${AWS_REGION}" \
--bucket "${BUCKET}"
else
aws s3api create-bucket \
--region "${AWS_REGION}" \
--bucket "${BUCKET}" \
--create-bucket-configuration LocationConstraint="${AWS_REGION}"
fi
# Enable versioning
aws s3api put-bucket-versioning \
--bucket "${BUCKET}" \
--versioning-configuration Status=Enabled
# Enable encryption with AES256 (simpler than KMS for state files)
aws s3api put-bucket-encryption \
--bucket "${BUCKET}" \
--server-side-encryption-configuration \
'{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"},"BucketKeyEnabled":true}]}'
# Block public access
aws s3api put-public-access-block \
--bucket "${BUCKET}" \
--public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
log "S3 bucket ${BUCKET} created successfully"
}
create_terraform_backend_tf() {
log "Creating backend.tf file"
cat > backend.tf <<EOF
terraform {
backend "s3" {
bucket = "${BUCKET}"
key = "${PROJECT}.tfstate"
region = "${AWS_REGION}"
}
}
EOF
log "backend.tf created successfully"
}
show_usage() {
echo "Usage: $0 [COMMAND]"
echo ""
echo "Commands:"
echo " setup - Create S3 bucket and backend.tf (default)"
echo " create_s3_bucket - Create S3 bucket only"
echo " create_backend_tf - Create backend.tf only"
echo " validate - Validate configuration only"
echo " help - Show this help"
echo ""
echo "Environment variables:"
echo " PROJECT - Project name (required)"
echo " AWS_REGION - AWS region (required)"
}
# Main execution
case "${1:-setup}" in
setup)
validate_config
create_terraform_s3_bucket
create_terraform_backend_tf
log "Terraform backend setup complete!"
log "Next steps: Run 'terraform init' to initialize the backend"
;;
create_s3_bucket)
validate_config
create_terraform_s3_bucket
;;
create_backend_tf)
validate_config
create_terraform_backend_tf
;;
validate)
validate_config
;;
help|--help|-h)
show_usage
;;
*)
error "Unknown command: $1. Use 'help' to see available commands."
;;
esac
@stefan-matic
Copy link
Author

Terraform can now do native S3 locking without DynamoDB so we need to adjust the script without the dynamoDB

hashicorp/terraform#35661

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment