Deploying and managing Google Cloud Storage for object storage
Google Cloud Storage is a globally unified, scalable, and highly durable object storage service for storing and accessing any amount of data. It provides industry-leading availability, performance, security, and management features.
Key Features
Global Accessibility: Access data from anywhere in the world
Scalability: Store and retrieve any amount of data at any time
Durability: 11 9's (99.999999999%) durability for stored objects
Storage Classes: Standard, Nearline, Coldline, and Archive storage tiers
Object Versioning: Maintain history and recover from accidental deletions
Object Lifecycle Management: Automatically transition and delete objects
Strong Consistency: Read-after-write and list consistency
Customer-Managed Encryption Keys (CMEK): Control encryption keys
Object Hold and Retention Policies: Enforce compliance requirements
VPC Service Controls: Add security perimeter around sensitive data
Cloud Storage Classes
Storage Class
Purpose
Minimum Storage Duration
Typical Use Cases
Standard
High-performance, frequent access
None
Website content, active data, mobile apps
Nearline
Low-frequency access
30 days
Data accessed less than once a month
Coldline
Very low-frequency access
90 days
Data accessed less than once a quarter
Archive
Data archiving, online backup
365 days
Long-term archive, disaster recovery
Deploying Cloud Storage with Terraform
Basic Bucket Creation
Advanced Configuration with Lifecycle Policies
Static Website Hosting Configuration
Managing Cloud Storage with gsutil
Basic Bucket Commands
Object Operations
Access Control
Lifecycle Management
Real-World Example: Multi-Region Data Lake Architecture
This example demonstrates a complete data lake architecture using Cloud Storage:
Architecture Overview
Landing Zone: Raw data ingestion bucket
Processing Zone: Data transformation and staging
Curated Zone: Processed, high-quality data
Archive Zone: Long-term, cold storage
Terraform Implementation
Data Lifecycle Automation Script
Best Practices
Bucket Naming and Organization
Choose globally unique, DNS-compliant names
Use consistent naming conventions
Organize objects with clear prefix hierarchy
Consider regional requirements for data storage
Security
Enable uniform bucket-level access
Use VPC Service Controls for sensitive data
Apply appropriate IAM roles with least privilege
Enforce public access prevention
Use CMEK for regulated data
Enable object holds for compliance
Cost Optimization
Choose appropriate storage classes for data access patterns
Implement lifecycle policies for automatic transitions
Use composite objects for small files
Monitor usage with Cloud Monitoring
Consider requester pays for shared datasets
Performance
Store frequently accessed data in regions close to users
Use parallel composite uploads for large files
Avoid small, frequent operations
Use signed URLs for temporary access
Implement connection pooling in applications
Data Management
Enable object versioning for critical data
Configure access logs for audit trails
Use object metadata for classification
Set up notifications for bucket events
Implement retention policies for compliance
Common Issues and Troubleshooting
Access Denied Errors
Verify IAM permissions and roles
Check for VPC Service Controls blocking access
Ensure service accounts have proper permissions
Validate CMEK access for encrypted buckets
Check organization policies for restrictions
Performance Issues
Review network configuration for private Google access
Ensure proper region selection for proximity to users
resource "google_storage_bucket" "static_assets" {
name = "my-static-assets-bucket"
location = "US"
storage_class = "STANDARD"
labels = {
environment = "production"
department = "engineering"
}
# Enable versioning for recovery
versioning {
enabled = true
}
# Use uniform bucket-level access (recommended)
uniform_bucket_level_access = true
# Public access prevention (recommended security setting)
public_access_prevention = "enforced"
}
# Grant access to a service account
resource "google_storage_bucket_iam_member" "viewer" {
bucket = google_storage_bucket.static_assets.name
role = "roles/storage.objectViewer"
member = "serviceAccount:my-service-account@my-project.iam.gserviceaccount.com"
}
resource "google_storage_bucket" "data_lake" {
name = "my-datalake-bucket"
location = "US-CENTRAL1"
storage_class = "STANDARD"
# Enable versioning
versioning {
enabled = true
}
# Enable object lifecycle management
lifecycle_rule {
condition {
age = 30 # days
}
action {
type = "SetStorageClass"
storage_class = "NEARLINE"
}
}
lifecycle_rule {
condition {
age = 90 # days
}
action {
type = "SetStorageClass"
storage_class = "COLDLINE"
}
}
lifecycle_rule {
condition {
age = 365 # days
}
action {
type = "SetStorageClass"
storage_class = "ARCHIVE"
}
}
# Delete old non-current versions
lifecycle_rule {
condition {
age = 30 # days
with_state = "ARCHIVED" # non-current versions
}
action {
type = "Delete"
}
}
# Use Customer-Managed Encryption Key (CMEK)
encryption {
default_kms_key_name = google_kms_crypto_key.bucket_key.id
}
# Other security settings
uniform_bucket_level_access = true
public_access_prevention = "enforced"
}
# Create KMS key for CMEK
resource "google_kms_key_ring" "storage_keyring" {
name = "storage-keyring"
location = "us-central1"
}
resource "google_kms_crypto_key" "bucket_key" {
name = "bucket-key"
key_ring = google_kms_key_ring.storage_keyring.id
}
# Grant Cloud Storage service account access to use KMS key
data "google_storage_project_service_account" "gcs_account" {}
resource "google_kms_crypto_key_iam_binding" "crypto_key_binding" {
crypto_key_id = google_kms_crypto_key.bucket_key.id
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
members = [
"serviceAccount:${data.google_storage_project_service_account.gcs_account.email_address}",
]
}
resource "google_storage_bucket" "website" {
name = "my-static-website-bucket"
location = "US"
storage_class = "STANDARD"
# Enable website serving
website {
main_page_suffix = "index.html"
not_found_page = "404.html"
}
# Set CORS configuration
cors {
origin = ["https://example.com"]
method = ["GET", "HEAD", "OPTIONS"]
response_header = ["Content-Type", "Access-Control-Allow-Origin"]
max_age_seconds = 3600
}
# Force bucket to serve content via HTTPS
force_destroy = true
}
# Make objects publicly readable
resource "google_storage_bucket_iam_member" "public_read" {
bucket = google_storage_bucket.website.name
role = "roles/storage.objectViewer"
member = "allUsers"
}
# Upload index page
resource "google_storage_bucket_object" "index" {
name = "index.html"
bucket = google_storage_bucket.website.name
source = "./website/index.html"
# Set content type
content_type = "text/html"
}
# Upload 404 page
resource "google_storage_bucket_object" "not_found" {
name = "404.html"
bucket = google_storage_bucket.website.name
source = "./website/404.html"
content_type = "text/html"
}
# Create a bucket
gsutil mb -l us-central1 gs://my-bucket
# List buckets
gsutil ls
# List objects in a bucket
gsutil ls gs://my-bucket/
# Get bucket information
gsutil ls -L gs://my-bucket
# Enable bucket versioning
gsutil versioning set on gs://my-bucket
# Set default storage class
gsutil defstorageclass set NEARLINE gs://my-bucket
# Upload file(s)
gsutil cp file.txt gs://my-bucket/
# Upload directory
gsutil cp -r ./local-dir gs://my-bucket/dir/
# Upload with specific content type
gsutil -h "Content-Type:text/html" cp index.html gs://my-bucket/
# Download file(s)
gsutil cp gs://my-bucket/file.txt ./
# Download directory
gsutil cp -r gs://my-bucket/dir/ ./local-dir/
# Move/Rename objects
gsutil mv gs://my-bucket/old-name.txt gs://my-bucket/new-name.txt
# Delete object
gsutil rm gs://my-bucket/file.txt
# Delete all objects in a bucket
gsutil rm gs://my-bucket/**
# Delete bucket and all its contents
gsutil rm -r gs://my-bucket
# Make object public
gsutil acl ch -u AllUsers:R gs://my-bucket/file.txt
# Set bucket-level IAM policy
gsutil iam ch serviceAccount:my-service@my-project.iam.gserviceaccount.com:objectViewer gs://my-bucket
# Get IAM policy
gsutil iam get gs://my-bucket
# Set uniform bucket-level access (recommended)
gsutil uniformbucketlevelaccess set on gs://my-bucket
# Disable public access
gsutil pap set enforced gs://my-bucket