openfaas / faas-cli

Official CLI for OpenFaaS
https://www.openfaas.com/
Other
794 stars 226 forks source link

Support secrets via `build` command passing --build-args to `docker build` #362

Closed rosskevin closed 6 years ago

rosskevin commented 6 years ago

Expected Behaviour

faas-cli build is responsible to for building the docker image amongst other things. To build a docker image that relies on any secret, the recommended way is with --build-arg FOO=${FOO}.

Here is a walkthrough of such a docker image build setup for node and an npm private package: https://docs.npmjs.com/private-modules/docker-and-private-modules

Without a change, faas-cli build cannot be used for functions that use both templates and private packages requiring secrets to build.

Current Behaviour

faas-cli build --build-arg NPM_TOKEN=${NPM_TOKEN}
Unknown flag: --build-arg

Possible Solution

A minimal solution is any --build-arg is passed through faas-cli build to docker build, this prevents secrets from neither being stored in any file nor any docker image layer.

Steps to Reproduce (for bugs)

  1. faas-cli build --build-arg NPM_TOKEN=${NPM_TOKEN}

Context

Cannot use openfaas with a private npm package.

This is a show-stopper as far as I know since all our code is private. The only workaround I can think of would be if I manually replicate the faas-build process. There may be another alternative but I am not aware of anything that could safely build with a secret. Perhaps going back to a complicated OnVault dockerfile would get it done, but I think this is a solution easily solved by allowing args to be passed through to docker build in some way.

Your Environment

ivanayov commented 6 years ago

Derek add label: proposal

alexellis commented 6 years ago

I would accept a PR for an additional --build-arg parameter to be passed to Docker. It would not be a YAML override though. It does raise some issues around when we want to use other services to run a faas-cli build which may not support --build-arg such as some of the interfaces for Moby's Buildkit (used in OpenFaaS Cloud).

FYI: build-time secrets or mounted files are not to my knowledge supported by Docker. A build-arg should be hidden from the final image but you should check this.

This is a show-stopper

This is overly dramatic language so I will give some more context around the various options for building your Node functions with OpenFaaS.

  1. Build the function with docker build

Any Docker image as long as it has the watchdog will work with OpenFaaS - this gives you 100% of the control on how you build and manage your images and where you do the builds is up to you. Full control.

  1. Build via an API / code

@LucasRoesler as Contiamo builds his functions via a service he created in Go. It's easy to connect to Docker in Go and issue build statements. Again this would allow you to re-use all the templates and customize it ad infinitum.

  1. With with official or custom templates

In this scenario you build via faas-cli build but can either use an official template or fork it for your language i.e. TypeScript.

Nothing stops you from wrapping faas-cli as part of a grunt or gulp task or some other process to pull your private npm modules and to place them in the correct place for the build. In fact this is probably your optimum solution outside of a PR.

Related: #262 #355

rosskevin commented 6 years ago

FYI: build-time secrets or mounted files are not to my knowledge supported by Docker. A build-arg should be hidden from the final image but you should check this.

https://docs.docker.com/engine/reference/commandline/build/ --build-arg |   | Set build-time variables - intent that these are ephemeral and not saved anywhere, therefore docker supports a built time secret through this mechanism. They do not have a vault or any other support for secrets, but this works for the simple cases where a secret is passed via environment variable.

With with official or custom templates

You cannot use with templates with secrets and faas-cli build if you cannot communicate the secret --build-arg to docker build. If you could faas-build --without-docker then you could follow it up with your own docker build --build-arg command. Otherwise, using templates means - as I mentioned - replicating the faas-cli build - which is doable but not desirable.

Unfortunately I'm not a go developer, proficient to expert in java, ruby, javascript, but not go - and I've got plenty on my plate so I won't be submitting a PR. I know this subject and am happy to pitch in knowledge and research if someone would like to take this up.

Since I want to use templates, it will be faster for me to replicate the faas-cli build process externally.

rosskevin commented 6 years ago

Looks like faas-cli build --shrinkwrap may be what I'm looking for in terms of merging code with a template (and without docker build), then I can follow up with custom build commands.

alexellis commented 6 years ago

So --shrinkwrap also looks useful for your use-case.

Unfortunately I'm not a go developer, proficient to expert in java, ruby, javascript, but not go - and I've got plenty on my plate so I won't be submitting a PR. I know this subject and am happy to pitch in knowledge and research if someone would like to take this up.

That would count as a contribution too.

I think the argument can be added reasonably quickly but I would ask for help testing it. Do you think having it only as a CLI argument would suit your use-case?

rosskevin commented 6 years ago

CLI-only arg is fine. I'm happy to test direct from a fork.

alexellis commented 6 years ago

@ross code is pushed up / tested in this branch - https://github.com/openfaas/faas-cli/pull/364

ross commented 6 years ago

You probably want @rosskevin :grin:

rosskevin commented 6 years ago

Hey @alexellis - thanks for the work on this. I'm going to pull and try and get this tested now before I leave - will be gone until Monday. Will get back to you shortly.

alexellis commented 6 years ago

Fixed and released 👍

alexellis commented 6 years ago

Thanks for input from everyone on the thread

alexellis commented 4 years ago

@feynmanliang

alexellis commented 4 years ago

Users can pass --build-arg now with arbitrary data and then consume it with an ARG line inside their Dockerfile.

https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact

alexellis commented 4 years ago

/lock: resolved

alexellis commented 4 years ago

Related - https://github.com/openfaas/faas-cli/pull/364