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
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"
}
Advanced Configuration with Lifecycle Policies
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}",
]
}
Static Website Hosting Configuration
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"
}
Managing Cloud Storage with gsutil
Basic Bucket Commands
# 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
Object Operations
# 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
Access Control
# 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