Automatically update Git repositories.
The common use case for autoupdate is to update Git repositories which contain Kubernetes resource files. The resources are then deployed automatically via autoapply (or similar projects).
In this first example, we will setup autoupdate in our Kubernetes cluster and configure CirlceCI to trigger the action during each build.
You can use minikube or kind to quickly setup a test cluster.
First, create a ConfigMap in the cluster. If you save the file as config.yaml
, you can create the object via kubectl apply -f ./config.yaml
.
apiVersion: v1
kind: ConfigMap
metadata:
name: autoupdate-config
data:
REPOSITORY_URL: https://git.example.com/repository
DEPLOYMENT_FILE: app.yaml
Then create a Secret with the credentials for authenticating autoupdate users.
Make sure to use a custom password (you can use pwgen 30 1
or openssl rand -hex 20
to generate a random string).
kubectl create secret generic autoupdate-secret \
--from-literal=USERS="username:password123"
Next, create the autoupdate deployment:
kubectl apply -f https://raw.githubusercontent.com/autoapply/autoupdate/master/docs/example-1/autoupdate-1.yaml
When the deployment is running, find the external IP address of the autoupdate service. We will need this for the last step.
After autoupdate has been setup, we need to adapt the CircleCI configuration. For this example, we assume that the CircleCI setup is similar to the one described in building-docker-images.
Add the following step to your configuration (.circleci/config.yml
).
Make sure to use the credentials from the earlier step and replace IP
with the external IP address of the autoupdate service.
Also, be careful to add this step after the step where the Docker image is pushed!
steps:
- run: curl -sS -u "username:password123" "http://IP/update?image=myapp&tag=0.1.${CIRCLE_BUILD_NUM}"
Now, whenever the CircleCI build runs, the autoupdate call will update the Git repository with the new Docker tag.
Based on the previous example, the update can also happen manually, whenever someone comments /deploy
on a pull request.
This could be achieved using GitHub Actions.
First, add the autoupdate username and password (see example 1) to the repository secrets.
The secret name should be AUTOUPDATE_AUTH
and the value needs to be in the form username:password
.
Then create the file .github/workflows/deploy.yml
in the GitHub repository where the comments should be given:
name: Deploy on comment
on:
issue_comment:
types: created
jobs:
deploy:
name: Deploy
if: github.event.comment.body == '/deploy'
runs-on: ubuntu-latest
steps:
- name: Deploy
env:
AUTOUPDATE_URL: http://IP/update
AUTOUPDATE_AUTH: ${{ secrets.AUTOUPDATE_AUTH }}
run: |
pull_request="$(jq -er .issue.number "${GITHUB_EVENT_PATH}")"
curl -sS -u "${AUTOUPDATE_AUTH}" "${AUTOUPDATE_URL}?image=myapp&tag=pr-${pull_request}"
Remember to replace the IP
with the external IP address of the autoupdate service (see example 1).
Now the autoupdate call will be triggered every time someone adds a new comment with the text /deploy
in a pull request.
This example assumes that your Docker images are tagged with the pull request number, like myapp:pr-123
. For another example, where the branch name is used instead, see example-2/deploy-2.yml.
When a new Docker image is pushed to the registry, it will not be used automatically by Kubernetes until the deployment is restarted.
This can be done manually using kubectl rollout restart
, but it could also be automated.
First, create a Secret with the credentials for authenticating autoupdate users.
Make sure to use a custom password (you can use pwgen 30 1
or openssl rand -hex 20
to generate a random string).
kubectl create secret generic autoupdate-secret \
--from-literal=USERS="username:password123"
Then create the autoupdate deployment:
kubectl apply -f https://raw.githubusercontent.com/autoapply/autoupdate/master/docs/example-3/autoupdate.yaml
When the deployment is running, find the external IP address of the autoupdate service.
The last step is to setup a trigger in the Docker registry.
This is different for each registry, the following is an example for the Azure Container Registry:
az acr webhook create \
--actions push \
--name autoupdate \
--registry myacr \
--scope "myapp:latest" \
--headers "Authorization=Basic 000000" \
--uri "http://IP/restart?deployment=mydeployment"
Make sure to set the correct authorization header. You can get the value from Kubernetes using kubectl get secret autoupdate-secret -o 'jsonpath={.data.USERS}'
.
Also remember to set IP
to the external IP address of the autoupdate service and use the correct values instead of myacr
, myapp
and mydeployment
.
Now, whenever the latest
tag is pushed to the registry, autoupdate will restart the deployment, so that Kubernetes will run the new image.
In the previous examples, we used the external IP address of the service. To use the DNS name instead, you could have a look at the external-dns project.
To automatically setup TLS for the service, you could use caddy or traefik.
autoupdate/autoupdate:latest
provides the basic image, running as autoupdate user (Dockerfile)autoupdate/autoupdate:root
provides the basic image, but running as root. This can be useful as a base for custom builds (Dockerfile)