Last active
October 30, 2025 21:12
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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 |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Terraform can now do native S3 locking without DynamoDB so we need to adjust the script without the dynamoDB
hashicorp/terraform#35661