woohaaha
How to set environment variables and secrets in Google App Engine (GAE)?
I am deploying a Phoenix app to Google App Engine (GAE). I am using elixir releases and am following this tutorial (https://cloud.google.com/community/tutorials/elixir-phoenix-on-google-app-engine). Once I deploy it appears that GAE reads an app.yaml file and then builds a container with the release inside it.
Setting secrets and environment variables has been a bit tricky. I sure enjoyed the way Heroku does it. It seems that GAE recommends making an http request to get those variables/secrets from another service. I don’t know enough about elixir releases to know where/how I’d make this http request and set the variables in this App Engine build process. Has anyone here successfully set environment variables in an App Engine Phoenix app? I’d love to hear how you did it. (If I had a preference I’d prefer not to make an HTTP request, and I’d also prefer not to compromise on security by setting them in the app.yaml)
Thank you
Most Liked
sezaru
I don’t know about GAE, but you can run HTTP requests or whatever inside a runtime.exs, that is what I do to communicate with Hashicorp Vault to retrieve secrets, etc only when my node starts.
Francesco
Hey I actually did sort something out a while ago.
In the application.ex start method I call a method called load_google_service_accounts. This then authenticates with Googles metadata server using the Goth package (as long as you are running on a google service such as GAE). Under the hood this uses the service account associated with the running service which it can do securely since you are on Googles infrastructure. Once authenticated you will get a token (from Goth) that you can use with the Google Secrets Manager API. You then fetch the secrets you want, and for easy access in the rest of the app you can store them in persistent_term.
defp load_google_service_accounts() do
# Load the secrets from Google Secrets Manager for use in relevant processes
{:ok, %{token: token}} = Goth.Token.for_scope(@secret_manager_scope)
{:ok, %{ payload: %{ data: secret_data }}} = GoogleApi.SecretManager.V1beta1.Connection.new(token)
|> GoogleApi.SecretManager.V1beta1.Api.Projects.secretmanager_projects_secrets_versions_access(@google_project_id, @secret_name, "latest")
decoded_data = secret_data |> Base.decode64! |> Jason.decode!
:persistent_term.put(:secret_name, GoogleServiceAccountKey.new(decoded_data))
end
Hope this helps
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









