Scaleway fournit un service de stockage d’objets compatibles avec l’API de S3.

Voici comment faire la configuration de votre bucket via Terraform*, bien qu’il soit complètement possible de la faire directement sur la console.

Voici le sommaire :

  1. Gestion des droits IAM
  2. Création du bucket
  3. Configuration de Ruby on Rails

Note: la variable var.scw_project contient l’UUID de votre projet que vous pouvez trouver dans la console.

Gestion des droits IAM

Nous allons tout d’abord créer une application afin de pouvoir lui assigner des droits et récupérer la paire de clés pour s’authentifier.

Ici, je lui accorde tous les droits (ObjectStorageFullAccess) pour l’API Object Storage mais vous pouvez être plus restrictifs.

# iam.tf

resource "scaleway_iam_application" "my_app" {
  name        = "MyApp"
  description = "MyApp application"
}

resource "scaleway_iam_api_key" "my_app" {
  application_id     = scaleway_iam_application.my_app.id
  description        = "MyApp API Key"
  default_project_id = var.scw_project
}

resource "scaleway_iam_policy" "my_app_object_storage" {
  name           = "MyApp Object Storage"
  description    = "Gives MyApp full access to object storage"
  application_id = scaleway_iam_application.my_app.id

  rule {
    project_ids          = [var.scw_project]
    permission_set_names = ["ObjectStorageFullAccess"]
  }
}

Ajoutez les outputs ci-dessous pour pouvoir récupérer la paire de clés d’authentification.

# outputs.tf

output "my_app_access_key" {
  value     = scaleway_iam_api_key.my_app.access_key
  sensitive = true
}

output "my_app_secret_key" {
  value     = scaleway_iam_api_key.my_app.secret_key
  sensitive = true
}

Création du bucket

Passons à la création du bucket, j’ai ajouté des règles pour migrer les objets d’un type de stockage à l’autre mais rien ne vous oblige à les utiliser. Les règles CORS sont importantes si vous souhaitez utiliser le direct uploads.

# object_storage.tf

resource "scaleway_object_bucket" "my_app" {
  name       = "my_app"
  region     = "fr-par"
  project_id = var.scw_project

  tags = {
    "Application" = "MyApp"
  }

  lifecycle_rule {
    id                                     = "abort_incomplete_multipart_upload"
    enabled                                = true
    abort_incomplete_multipart_upload_days = 7
  }

  lifecycle_rule {
    id      = "onezone_ia"
    enabled = true

    transition {
      days          = 30
      storage_class = "ONEZONE_IA"
    }
  }

  lifecycle_rule {
    id      = "glacier"
    enabled = true

    transition {
      days          = 120
      storage_class = "GLACIER"
    }
  }

  cors_rule {
    allowed_methods = ["GET", "HEAD", "POST", "PUT", "DELETE"]
    allowed_headers = ["*"]
    allowed_origins = [
      "*"
    ]
    expose_headers  = ["ETag"]
    max_age_seconds = 3600
  }
}

The last thing we need to configure here is the bucket policy to ensure that the application can use it. Note that I added a rule for my user so I can still access the bucket from the console.

# object_storage.tf

resource "scaleway_object_bucket_policy" "my_app" {
  bucket = scaleway_object_bucket.my_app.name

  policy = jsonencode({
    Id      = "my_app",
    Version = "2023-04-17",
    Statement = [
      {
        Effect    = "Allow"
        Action    = ["*"]
        Principal = { SCW = "application_id:${scaleway_iam_application.my_app.id}" }
        Resource = [
          scaleway_object_bucket.my_app.name,
          "${scaleway_object_bucket.my_app.name}/*",
        ]
      },
      {
        Effect    = "Allow"
        Action    = ["*"]
        Principal = { SCW = "user_id:${var.scw_my_user}" }
        Resource = [
          scaleway_object_bucket.my_app.name,
          "${scaleway_object_bucket.my_app.name}/*",
        ]
      }
    ]
  })
}

Configuration de Ruby on Rails

Nous pouvons à présent configurer Active Storage avec notre configuration.

# config/storage.yml

scaleway:
  service: S3
  access_key_id: <%= Rails.application.credentials.dig(:scaleway, :access_key) %>
  secret_access_key: <%= Rails.application.credentials.dig(:scaleway, :secret_key) %>
  region: fr-par
  bucket: my_app
  endpoint: https://s3.fr-par.scw.cloud

Récupérez la paire de clés avec les commandes ci-dessous :

tf output my_app_access_key
tf output my_app_secret_key

Et voilà !