Mount a file as a volume in Cloud Run

guillaume blaquiere
Google Cloud - Community
3 min readJul 27, 2021

Cloud Run has redefined the serverless paradigm a few years ago. Cloud Run has also made a promise: portability on any Kubernetes cluster with Knative installed on top of them. I demonstrated this portability which is great!

Knative and Cloud Run implement the same APIs and the same principle: You create a container, you deploy it, and it scales automatically according to your traffic.

To ensure and to achieve this scalability, Cloud Run and Knative come with a major constraint in the container paradigm

The container must be stateless. You can’t mount a volume on your container

So, today (July 2021): It’s impossible to mount a volume on Cloud Run. But….

Secret management on Cloud Run

Cloud Run hosts applications’ services and, like most of apps, they need to have access to secrets: API Keys, database credentials, private keys,…
On Google Cloud, the recommended tool to manage secrets is Secret Manager.

Cloud Run proposes a convenient integration with Secret Manager, and because Cloud Run wants to be as portable as possible on any Kubernetes cluster, it implements similar secret management features. You can load a secret value:

  • Either into environment variables
  • Or mount it as a volume.

Mount a secret as a volume in Cloud Run

This feature is great and compliant with Kubernetes best practices. To achieve it with Cloud Run, you need to create a secret in Secret Manager :

# Create a secret name
gcloud secrets create medium
# Create a secret version
echo "my secret" | gcloud secrets versions add --data-file=- medium

Then, you can deploy your Cloud Run service with the secret mounted as a volume :

gcloud beta run deploy <SERVICE_NAME> --image <IMAGE> \
--update-secrets=/secrets/mysecret=medium:latest

And, finally, read it as any file from your service, here in Golang for example (file server.go) :

package main

import (
"fmt"
"io/ioutil"
"net/http"
"os"
)
var fileLocation = "/secrets/mysecret"func main() {

http.HandleFunc("/", func (w http.ResponseWriter,
r *http.Request) {
f, err :=os.Open(fileLocation)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprint(w,err)
return
}
b, err := ioutil.ReadAll(f)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
fmt.Fprint(w,err)
return
}
fmt.Println(string(b))
fmt.Fprint(w,string(b))
return
})
http.ListenAndServe(":8080", nil)
}

Call your service and Yeah, you have my secret displayed! You successfully mount a secret as a file and read it in your code!

Hey you read a secret as a file! Why not read a secret file as a file?

Mount a (secret) file in Cloud Run

Similarly as a secret value, you can create a secret from a file! Let’s load a file as a secret, like that :

gcloud secrets versions add --data-file=./server.go medium

Try again and Boom, you have mounted a file in Cloud Run!!
You can get the latest version of the secret immediately because we defined the latest version of the medium secret during the deployment. You can define a static version if you prefer.

Use cases and limits

Before discussing the use cases, let’s have a look at the limits:

  • You can only read the file content, not write or update it, except if you create a new secret version
  • Your secret content is limited to 64KiB

Because of those constraints, the best use case is to load a configuration file as a volume.

  • A configuration file doesn’t need to be updated by the application
  • A configuration file can contain secrets
  • A configuration file is small and fits within the 64KiB constraint

Of course, you can load several (secret) files in different volumes when you deploy your Cloud Run service.

Cloud Run and Volumes

Cloud Run does not yet support the volumes, but you can simulate this support thanks to Secret Manager integration and for a specific use case. I used it for a Spring boot deployment and it’s really helpful!

It’s great for configuration, secret management and to prevent to push sensitive data in Git repository.

--

--

guillaume blaquiere
Google Cloud - Community

GDE cloud platform, Group Data Architect @Carrefour, speaker, writer and polyglot developer, Google Cloud platform 3x certified, serverless addict and Go fan.