Skip to main content

Use buckets from Cloider apps and Kubernetes

Apps and Kubernetes workloads on Cloider reach buckets the same way any other program does: with the S3 endpoint and an access key, passed in as environment variables. This page shows how to create a key for a workload, hand it to an App Engine app or a Kubernetes cluster, and use it from code.

The environment variables​

Every AWS SDK, the AWS CLI and most S3 libraries read these variables on their own, so your code doesn't need any Cloider specific configuration:

Environment
AWS_ACCESS_KEY_ID=CLDRZ8Q4M2X7KD1PLW0B
AWS_SECRET_ACCESS_KEY=7hT2kV9qWm4LxR8zNc3PbY6sJd1FgA5eUo0iKlMn
AWS_REGION=eu-central-2
AWS_ENDPOINT_URL_S3=https://s3.eu-central-2.cloider.com
AWS_REQUEST_CHECKSUM_CALCULATION=when_required
AWS_RESPONSE_CHECKSUM_VALIDATION=when_required
S3_BUCKET=acme-assets
VariableRead byPurpose
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEYAll AWS SDKs and the AWS CLIThe access key
AWS_REGIONAll AWS SDKs and the AWS CLIThe region requests are signed for
AWS_ENDPOINT_URL_S3Recent AWS SDKs and the AWS CLISends S3 requests to Cloider. AWS_ENDPOINT_URL does the same for every AWS service
AWS_REQUEST_CHECKSUM_CALCULATION, AWS_RESPONSE_CHECKSUM_VALIDATIONAWS SDKs and CLI from 2025Keeps uploads compatible, see Troubleshooting
S3_BUCKETYour codeThe bucket name. A convention, not read by SDKs

Frameworks often use their own names (Laravel's AWS_BUCKET and AWS_ENDPOINT, for example). See SDKs for framework configurations.

Create a key for the workload​

Give each workload its own key, scoped to the buckets it uses, so you can rotate or revoke it on its own:

cloider bucket key create --label api-production --bucket acme-assets

Use a read only key (--read-only) for workloads that only read, such as a service that serves images. See Access keys.

Use a bucket from an App Engine app​

An app gets the key as environment variables. Store the secret key as a secret variable, so it is never listed back. Changing variables restarts the app.

  1. Create an access key for the bucket and copy its access key id and secret.
  2. Open Apps in the sidebar, click the app, and select the Environment tab.
  3. Add the variables from the list above, with AWS_SECRET_ACCESS_KEY as a secret.
  4. Save. The app restarts with the new variables.

Use a bucket from a Kubernetes cluster​

In a Kubernetes cluster, store the key in a Secret and load it into your pods as environment variables. Pods reach the bucket on its public HTTPS endpoint, like any other client.

s3-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: s3
namespace: default
type: Opaque
stringData:
AWS_ACCESS_KEY_ID: CLDRZ8Q4M2X7KD1PLW0B
AWS_SECRET_ACCESS_KEY: 7hT2kV9qWm4LxR8zNc3PbY6sJd1FgA5eUo0iKlMn
AWS_REGION: eu-central-2
AWS_ENDPOINT_URL_S3: https://s3.eu-central-2.cloider.com
AWS_REQUEST_CHECKSUM_CALCULATION: when_required
AWS_RESPONSE_CHECKSUM_VALIDATION: when_required
S3_BUCKET: acme-assets

Or create it without writing the secret to a file:

kubectl create secret generic s3 \
--from-literal=AWS_ACCESS_KEY_ID=CLDRZ8Q4M2X7KD1PLW0B \
--from-literal=AWS_SECRET_ACCESS_KEY="$S3_SECRET_KEY" \
--from-literal=AWS_REGION=eu-central-2 \
--from-literal=AWS_ENDPOINT_URL_S3=https://s3.eu-central-2.cloider.com \
--from-literal=AWS_REQUEST_CHECKSUM_CALCULATION=when_required \
--from-literal=AWS_RESPONSE_CHECKSUM_VALIDATION=when_required \
--from-literal=S3_BUCKET=acme-assets

Load every key of the Secret into a Deployment's containers with envFrom:

deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
spec:
replicas: 2
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: registry.cloider.com/acme/api:1.0
envFrom:
- secretRef:
name: s3
kubectl apply -f s3-secret.yaml -f deployment.yaml

Check from inside a pod that the bucket is reachable:

kubectl run s3-check --rm -it --restart=Never --image=amazon/aws-cli \
--overrides='{"spec":{"containers":[{"name":"s3-check","image":"amazon/aws-cli","args":["s3","ls","s3://acme-assets"],"envFrom":[{"secretRef":{"name":"s3"}}]}]}}'

With Terraform​

The cloider_bucket_key outputs can feed a kubernetes_secret_v1 directly, so the secret never leaves Terraform:

main.tf
resource "cloider_bucket" "assets" {
name = "acme-assets"
}

resource "cloider_bucket_key" "api" {
label = "api-production"
buckets = [cloider_bucket.assets.id]
}

resource "kubernetes_secret_v1" "s3" {
metadata {
name = "s3"
namespace = "default"
}

data = {
AWS_ACCESS_KEY_ID = cloider_bucket_key.api.access_key
AWS_SECRET_ACCESS_KEY = cloider_bucket_key.api.secret_key
AWS_REGION = cloider_bucket.assets.region
AWS_ENDPOINT_URL_S3 = cloider_bucket.assets.endpoint
AWS_REQUEST_CHECKSUM_CALCULATION = "when_required"
AWS_RESPONSE_CHECKSUM_VALIDATION = "when_required"
S3_BUCKET = cloider_bucket.assets.name
}
}

Configure the kubernetes provider for your cluster as shown in Kubernetes and Helm with Terraform.

Use the bucket from code​

With the variables in place, a client created without options talks to Cloider:

import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

const s3 = new S3Client({}); // reads AWS_* from the environment

await s3.send(new PutObjectCommand({
Bucket: process.env.S3_BUCKET,
Key: "uploads/hello.txt",
Body: "Hello from my app",
}));

This relies on SDK versions that read AWS_ENDPOINT_URL_S3 and the checksum variables. With older versions, set the endpoint in code as shown in SDKs.

Good practices​

  • One key per workload and environment. api-staging and api-production with their own keys, scoped to their own buckets (for example acme-assets-staging and acme-assets).
  • Keep the secret out of images and repositories. Use secret app variables or Kubernetes Secrets, never a Dockerfile ENV or a committed .env file.
  • Rotate without downtime. Create the new key, update the variables or the Secret (apps restart on their own, Deployments need kubectl rollout restart deployment/api), then delete the old key. See Rotate an access key.
  • Serve public files by URL. If the app only hands files to browsers, a public bucket or presigned URLs avoid streaming them through the app.

Next steps​

Frequently asked questions

How do I connect a Cloider app to a bucket?

Create an access key for the bucket, then set AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY (as a secret), AWS_REGION=eu-central-2, AWS_ENDPOINT_URL_S3=https://s3.eu-central-2.cloider.com and the two checksum variables as the app's environment variables. The AWS SDKs read them on their own.

How do I give a Kubernetes pod access to a Cloider bucket?

Store the access key, region, endpoint and checksum settings in a Kubernetes Secret and load it into the container with envFrom and secretRef. Pods reach the bucket on its public HTTPS endpoint.

Do apps and clusters get access to buckets automatically?

No. Every workload needs an access key, which you pass in as environment variables. Give each workload its own key, scoped to the buckets it uses.