Skip to content

S3 Configuration Example

This example demonstrates how to configure S3 server settings, buckets, access keys, and bucket policies on an existing Qumulo cluster.

Features

  • S3 server settings configuration (enable S3, base path, security)
  • Buckets with versioning and Object Lock support
  • S3 access key management for applications
  • Bucket policies with JSON IAM-style permissions
  • Multiple buckets using for_each for scalable management

Prerequisites

  1. An existing Qumulo cluster with REST API access (Qumulo Core 7.0+)
  2. Admin credentials for the cluster
  3. Network connectivity to the cluster endpoint
  4. A local user account for S3 access key creation

Usage

  1. Initialize, plan, and apply with your cluster variables:
    terraform init -upgrade
    terraform plan \
      -var="cluster_endpoint=https://your-cluster:8000" \
      -var="cluster_password=your-password"
    terraform apply \
      -var="cluster_endpoint=https://your-cluster:8000" \
      -var="cluster_password=your-password"
    

Or create a terraform.tfvars file with your values and run terraform apply without -var flags.

Configuration

Variables

Name Description Type Required
cluster_endpoint Qumulo cluster REST API endpoint string Yes
cluster_username Cluster admin username string No (default: admin)
cluster_password Cluster admin password string Yes
project_buckets Map of project bucket configs map(object) No

Outputs

Name Description
s3_enabled Whether S3 is enabled on the cluster
data_bucket_name Name of the data bucket
compliance_bucket_name Name of the compliance bucket
app_access_key_id Access key ID for the application
app_secret_access_key Secret access key (sensitive)
project_bucket_ids Map of project names to creation times

S3 Settings

The qumulo_s3_settings resource configures global S3 server settings:

resource "qumulo_s3_settings" "main" {
  connection_profile = "cluster1"

  enabled   = true
  base_path = "/s3-buckets"        # Base directory for buckets
  secure    = false                 # HTTPS-only mode
  multipart_upload_expiry_interval = "7days"
}

S3 Buckets

Create buckets with optional versioning and Object Lock:

resource "qumulo_s3_bucket" "data" {
  connection_profile = "cluster1"

  name                = "my-bucket"
  path                = "/s3-buckets/my-bucket"
  create_fs_path      = true
  object_lock_enabled = true    # Immutable after creation
  versioning          = "Enabled"

  lock_config {
    enabled = true
    default_retention {
      units = "DAYS"    # or "YEARS"
      value = 30
    }
  }
}

Versioning Options

Value Description
Unversioned No versioning (default for new buckets)
Enabled Keep all versions of objects
Suspended Stop creating new versions

S3 Access Keys

Create access keys for S3 API authentication:

resource "qumulo_s3_access_key" "app" {
  connection_profile = "cluster1"

  user {
    domain = "LOCAL"        # LOCAL, ACTIVE_DIRECTORY, or POSIX_USER
    name   = "app-user"
  }
}

output "secret_key" {
  value     = qumulo_s3_access_key.app.secret_access_key
  sensitive = true
}

Important: The secret_access_key is only returned at creation time and stored in Terraform state. Changing any user attributes will force recreation and generate a new key pair.

Bucket Policies

Apply IAM-style bucket policies:

resource "qumulo_s3_bucket_policy" "data" {
  connection_profile = "cluster1"

  bucket_name = qumulo_s3_bucket.data.name

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Sid       = "AllowAppAccess"
      Effect    = "Allow"
      Principal = "local:app-user"
      Action    = ["s3:GetObject", "s3:PutObject"]
      Resource  = ["arn:aws:s3:::my-bucket/*"]
    }]
  })
}

Principal Formats

Format Example Description
Local user local:username Local Qumulo user
AD user ad:DOMAIN\username Active Directory user
Everyone * Anonymous access

Security Considerations

  • Store cluster_password in a secure location (environment variable, secrets manager)
  • The secret_access_key is sensitive and only available at creation; store it securely
  • Use bucket policies to implement least-privilege access
  • Enable secure = true in S3 settings to require HTTPS
  • Consider Object Lock for compliance requirements (immutable data)
  • Access keys cannot be updated; changes require recreation

Full Configuration

# Example: Managing S3 on a Qumulo Cluster
#
# This example demonstrates how to configure S3 server settings,
# create buckets with versioning and Object Lock, manage access keys,
# and apply bucket policies on a Qumulo cluster.

terraform {
  required_providers {
    qumulo = {
      source  = "qumulo-terraform-registry.s3.us-east-1.amazonaws.com/qumulo/qumulo"
      version = "~> 1.0"
    }
  }
}

variable "cluster_endpoint" {
  description = "Qumulo cluster REST API endpoint (e.g., https://cluster:8000)"
  type        = string
}

variable "cluster_username" {
  description = "Qumulo cluster admin username"
  type        = string
  default     = "admin"
}

variable "cluster_password" {
  description = "Qumulo cluster admin password"
  type        = string
  sensitive   = true
}

# Define connection profile for the cluster
provider "qumulo" {
  connection_profiles = [
    {
      name                 = "cluster1"
      endpoint             = var.cluster_endpoint
      username             = var.cluster_username
      password             = var.cluster_password
      insecure_skip_verify = true # Required for clusters with self-signed certificates
    }
  ]
}

# Configure S3 server settings
resource "qumulo_s3_settings" "main" {
  connection_profile = "cluster1"

  enabled   = true
  base_path = "/s3-buckets"
  secure    = false

  # Expire incomplete multipart uploads after 7 days
  multipart_upload_expiry_interval = "7days"
}

# Create an S3 bucket with versioning
resource "qumulo_s3_bucket" "data" {
  connection_profile = "cluster1"

  name           = "data-bucket"
  path           = "/s3-buckets/data-bucket"
  create_fs_path = true
  versioning     = "Enabled"

  # Object Lock configuration (required by schema, disabled for this bucket)
  lock_config {
    enabled = false
    default_retention {
      units = "DAYS"
      value = 1
    }
  }

  depends_on = [qumulo_s3_settings.main]
}

# Create an S3 bucket with Object Lock for compliance
resource "qumulo_s3_bucket" "compliance" {
  connection_profile = "cluster1"

  name                = "compliance-bucket"
  path                = "/s3-buckets/compliance-bucket"
  create_fs_path      = true
  object_lock_enabled = true
  versioning          = "Enabled"

  lock_config {
    enabled = true
    default_retention {
      units = "DAYS"
      value = 30
    }
  }

  depends_on = [qumulo_s3_settings.main]
}

# Create an S3 access key for an application
resource "qumulo_s3_access_key" "app" {
  connection_profile = "cluster1"

  user {
    domain = "LOCAL"
    name   = "app-user"
  }
}

# Apply a bucket policy to the data bucket
resource "qumulo_s3_bucket_policy" "data" {
  connection_profile = "cluster1"

  bucket_name = qumulo_s3_bucket.data.name

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid       = "AllowAppUserAccess"
        Effect    = "Allow"
        Principal = "local:app-user"
        Action = [
          "s3:GetObject",
          "s3:PutObject",
          "s3:DeleteObject",
          "s3:ListBucket"
        ]
        Resource = [
          "arn:aws:s3:::data-bucket",
          "arn:aws:s3:::data-bucket/*"
        ]
      }
    ]
  })
}

# Create multiple buckets using for_each
variable "project_buckets" {
  description = "Map of project bucket configurations"
  type = map(object({
    versioning = string
  }))
  default = {
    "project-alpha" = { versioning = "Enabled" }
    "project-beta"  = { versioning = "Suspended" }
    "project-gamma" = { versioning = "Unversioned" }
  }
}

resource "qumulo_s3_bucket" "projects" {
  for_each = var.project_buckets

  connection_profile = "cluster1"

  name           = each.key
  path           = "/s3-buckets/${each.key}"
  create_fs_path = true
  versioning     = each.value.versioning

  # Object Lock configuration (required by schema, disabled for this bucket)
  lock_config {
    enabled = false
    default_retention {
      units = "DAYS"
      value = 1
    }
  }

  depends_on = [qumulo_s3_settings.main]
}

# Outputs
output "s3_enabled" {
  description = "Whether S3 is enabled on the cluster"
  value       = qumulo_s3_settings.main.enabled
}

output "data_bucket_name" {
  description = "Name of the data bucket"
  value       = qumulo_s3_bucket.data.name
}

output "compliance_bucket_name" {
  description = "Name of the compliance bucket"
  value       = qumulo_s3_bucket.compliance.name
}

output "app_access_key_id" {
  description = "Access key ID for the application"
  value       = qumulo_s3_access_key.app.access_key_id
}

output "app_secret_access_key" {
  description = "Secret access key for the application (sensitive)"
  value       = qumulo_s3_access_key.app.secret_access_key
  sensitive   = true
}

output "project_bucket_ids" {
  description = "Map of project bucket names to creation times"
  value       = { for k, v in qumulo_s3_bucket.projects : k => v.creation_time }
}