|
| 1 | +--- |
| 2 | +title: "Deploy your functions to OpenFaaS with Github Actions" |
| 3 | +description: "Bring CI/CD to your OpenFaaS deployment with Github Actions." |
| 4 | +date: 2020-10-08 |
| 5 | +image: /images/2020-10-08-openfaas-functions-with-github-actions/lego.jpg |
| 6 | +categories: |
| 7 | + - faas-netes |
| 8 | + - faasd |
| 9 | + - cicd |
| 10 | + - github |
| 11 | + - multi-arch |
| 12 | +author_staff_member: utsav |
| 13 | +dark_background: true |
| 14 | +--- |
| 15 | + |
| 16 | +Learn how to bring CI-CD to your OpenFaaS functions with Github Actions |
| 17 | + |
| 18 | +## Who should read this? |
| 19 | + |
| 20 | +OpenFaaS was created to have the freedom to run serverless functions anywhere, be it on a Raspberry Pi, in a data center, or the cloud. This started with faas-swarm to run on Docker Swarm and faas-netes to run on Kubernetes. faas-netes is the current recommendation for running OpenFaaS in production. |
| 21 | +If you're not a large team, or just someone who doesn't want to deal with the complexities that comes with Kubernetes then you're much better off with faasd. |
| 22 | + |
| 23 | +But whatever shape or form you're running OpenFaaS as, if you want more automation for how your functions are built and deployed with Github Actions, this will be a good read for you. |
| 24 | + |
| 25 | +In this tutorial, we'll see how we can get OpenFaaS functions up and running with Github Actions on a faas-netes deployment running on GKE, but the same approach is valid for all forms of OpenFaaS as it exists today whether it is faas-netes or faasd, running either in the cloud or on your desk. |
| 26 | + |
| 27 | + |
| 28 | +## Prerequisites |
| 29 | + |
| 30 | +* An OpenFaaS deployment that is accessible from the internet |
| 31 | + |
| 32 | +Get started with the official documentation [here](https://docs.openfaas.com/deployment/) |
| 33 | + |
| 34 | +* faas-cli |
| 35 | + |
| 36 | +faas-cli is a command line tool used to interact with OpenFaaS, from deploying your functions to viewing logs. |
| 37 | +Follow the installation instructions [here](https://docs.openfaas.com/cli/install/) |
| 38 | + |
| 39 | +> You can follow along with the code used in this tutorial from this [repo](https://github.com/utsavanand2/hello) |
| 40 | +
|
| 41 | + |
| 42 | +## Create an OpenFaaS function |
| 43 | + |
| 44 | +I'm going to create and deploy a Golang function for this tutorial. |
| 45 | + |
| 46 | +```sh |
| 47 | +# create a new directory for our project |
| 48 | +mkdir hello |
| 49 | +# pull golang-http templates |
| 50 | +faas-cli template store pull golang-http |
| 51 | +# create a new function with faas-cli |
| 52 | +faas-cli new hello --lang golang-http |
| 53 | +``` |
| 54 | + |
| 55 | +If you look into the root directory of the project, faas-cli has created two additional files: |
| 56 | + |
| 57 | +``` |
| 58 | +./hello/handler.go |
| 59 | +./hello.yml |
| 60 | +``` |
| 61 | + |
| 62 | +The content of our handler looks something like this: |
| 63 | + |
| 64 | + |
| 65 | +The YAML file is used to configure the deployment and the build and runtime environment of the function |
| 66 | + |
| 67 | + |
| 68 | +## Setup a workflow file for Github Actions |
| 69 | + |
| 70 | +[Github Action workflows](https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/introduction-to-github-actions) is one of the many core components of Github Actions that lets users add an automated workflow that executes on an event, and can be used to test, build and deploy our code. |
| 71 | +A workflow can be composed of multiple steps, each executing a particular action. |
| 72 | +There are many published [Actions](https://github.com/marketplace?type=actions) that provide nice wrappers for common actions and tools making them easier to use, but we can also use any published Docker image. The OpenFaaS team already publishes an image for `faas-cli` that is ready to use for any workflow. |
| 73 | + |
| 74 | +Our workflow is a simple linear process: |
| 75 | +`Checkout` -> `Pull Templates` -> `ShrinkWrap Build` -> `OpenFaaS Login` -> `Docker Login` -> `Docker Buildx Setup` -> `Build & Push Function` -> `Deploy to OpenFaaS` |
| 76 | + |
| 77 | +In the root directory of the project run: |
| 78 | + |
| 79 | +```sh |
| 80 | +mkdir -p .github/workflows |
| 81 | +nano ./github/workflows/main.yml |
| 82 | +``` |
| 83 | + |
| 84 | +And paste in the following contents into main.yml file |
| 85 | + |
| 86 | +```yaml |
| 87 | +name: CI/CD |
| 88 | + |
| 89 | +on: |
| 90 | + push: |
| 91 | + branches: |
| 92 | + - master |
| 93 | +jobs: |
| 94 | + func-build: |
| 95 | + runs-on: ubuntu-latest |
| 96 | + steps: |
| 97 | + - |
| 98 | + name: Checkout |
| 99 | + uses: actions/checkout@v2 |
| 100 | + - |
| 101 | + name: Pull template |
| 102 | + uses: docker://openfaas/faas-cli:latest-root |
| 103 | + with: |
| 104 | + args: template store pull golang-http |
| 105 | + - |
| 106 | + name: Run shrinkwrap build |
| 107 | + uses: docker://openfaas/faas-cli:latest-root |
| 108 | + with: |
| 109 | + args: build -f hello.yml --shrinkwrap |
| 110 | + - |
| 111 | + name: Login to OpenFaaS Gateway |
| 112 | + uses: docker://openfaas/faas-cli:latest-root |
| 113 | + with: |
| 114 | + args: login -p {% raw %}${{ secrets.OPENFAAS_GATEWAY_PASSWD }}{% endraw %} -g {% raw %}${{ secrets.OPENFAAS_GATEWAY }}{% endraw %} |
| 115 | + - |
| 116 | + name: Login to DockerHub |
| 117 | + if: success() |
| 118 | + uses: docker/login-action@v1 |
| 119 | + with: |
| 120 | + username: {% raw %}${{ secrets.DOCKER_USERNAME }}{% endraw %} |
| 121 | + password: {% raw %}${{ secrets.DOCKER_PASSWORD }}{% endraw %} |
| 122 | + - |
| 123 | + name: Set up Docker Buildx |
| 124 | + uses: docker/setup-buildx-action@v1 |
| 125 | + - |
| 126 | + name: Build and Push the OpenFaaS function |
| 127 | + uses: docker/build-push-action@v2 |
| 128 | + with: |
| 129 | + context: ./build/hello/ |
| 130 | + file: ./build/hello/Dockerfile |
| 131 | + push: true |
| 132 | + tags: utsavanand2/hello:latest |
| 133 | + - |
| 134 | + name: Deploying the OpenFaaS function |
| 135 | + uses: docker://openfaas/faas-cli:latest-root |
| 136 | + with: |
| 137 | + args: deploy -f hello.yml |
| 138 | +``` |
| 139 | +
|
| 140 | +> Note: Replace the Docker UserID from the image tag name with your own. |
| 141 | +
|
| 142 | +Since Github Actions requires us to use a Docker image that has a root user invoking the commands using the Docker action, so we're using the root variant of the faas-cli Docker image. Read more about it [here](https://docs.github.com/en/free-pro-team@latest/actions/creating-actions/dockerfile-support-for-github-actions#user) |
| 143 | +
|
| 144 | +The faas-cli:latest-root image has the faas-cli installed as the entrypoint, so everything set in args is passed to the faas-cli. |
| 145 | +This will work with any of the faas-cli root tags, you can pin to any specific version of faas-cli, for example: `openfaas/faas-cli:0.12.14-root`. |
| 146 | + |
| 147 | +## Create and configure a Github Repo with Github Actions |
| 148 | + |
| 149 | +Initialize a git repo in the root directory of the project |
| 150 | + |
| 151 | +```sh |
| 152 | +# Initialize a git repo |
| 153 | +git init |
| 154 | +# Add a remote |
| 155 | +git remote add origin https://github.com/<Your-Github-Username>/hello.git |
| 156 | +# Stage and commit your changes |
| 157 | +git add . |
| 158 | +git commit -m "Initial Commit" |
| 159 | +``` |
| 160 | + |
| 161 | +Create a Github Repo named hello and add the following secrets and their values to the repo for Github Actions to build push and deploy your OpenFaaS functions. Make sure that the secret names correspond with the Github workflow YAML file as defined above in the previous section. |
| 162 | + |
| 163 | + |
| 164 | + |
| 165 | +## Push the repo to Github to trigger Github Actions |
| 166 | + |
| 167 | +```sh |
| 168 | +git push -u origin master |
| 169 | +``` |
| 170 | + |
| 171 | +## Check the status of your Github Actions build |
| 172 | + |
| 173 | +Under the `Actions` tab we can check the status of the workflow |
| 174 | + |
| 175 | + |
| 176 | + |
| 177 | +Since we have successfully built and deployed our functions let's invoke it with curl. |
| 178 | + |
| 179 | +## Invoke the function with curl |
| 180 | + |
| 181 | +```sh |
| 182 | +export OPENFAAS_GATEWAY=<The OPENFAAS_GATEWAY of your OpenFaaS deployment> |
| 183 | +curl http://$OPENFAAS_GATEWAY/function/hello |
| 184 | +``` |
| 185 | + |
| 186 | + |
| 187 | + |
| 188 | +## Take it further |
| 189 | + |
| 190 | +You can take this to the next level by leveraging multi-arch builds with Docker's [Buildx](https://docs.docker.com/buildx/working-with-buildx/) and the golang-http-templates which now support multi-arch builds. This means that you can deploy the same function to architectures like arm, arm64 of amd64 from a single build. |
| 191 | + |
| 192 | +Just add a step to setup `QEMU` and pass a `platforms` key in the build step, making the last few steps concerned with Docker look something like this: |
| 193 | + |
| 194 | +```yaml |
| 195 | + - |
| 196 | + name: Login to DockerHub |
| 197 | + if: success() |
| 198 | + uses: docker/login-action@v1 |
| 199 | + with: |
| 200 | + username: {% raw %}${{ secrets.DOCKER_USERNAME }}{% endraw %} |
| 201 | + password: {% raw %}${{ secrets.DOCKER_PASSWORD }}{% endraw %} |
| 202 | + - |
| 203 | + name: Set up QEMU |
| 204 | + uses: docker/setup-qemu-action@v1 |
| 205 | + - |
| 206 | + name: Set up Docker Buildx |
| 207 | + uses: docker/setup-buildx-action@v1 |
| 208 | + - |
| 209 | + name: Build and Push the OpenFaaS function |
| 210 | + uses: docker/build-push-action@v2 |
| 211 | + with: |
| 212 | + context: ./build/hello/ |
| 213 | + file: ./build/hello/Dockerfile |
| 214 | + push: true |
| 215 | + platforms: linux/amd64,linux/arm64,linux/arm/v7 |
| 216 | + tags: utsavanand2/hello:latest |
| 217 | +``` |
| 218 | + |
| 219 | +You can checkout the workflow YAML supporting multi-arch builds [here](https://github.com/utsavanand2/hello/blob/multi-arch/.github/workflows/main.yml): |
| 220 | + |
| 221 | + |
| 222 | + |
| 223 | +## Acknowledgements |
| 224 | + |
| 225 | +Special Thanks to [Lucas Rosler](https://twitter.com/TheAxeR) and [Alex Ellis](https://twitter.com/alexellisuk) for all the precious advice and helping me out with making faas-cli more portable for CI environments than ever before. |
| 226 | + |
| 227 | +Thanks to [Dan Burton](https://unsplash.com/@single_lens_reflex) for the background picture. |
0 commit comments