For a working example see kube-template
Manages DigitalOcean Kubernetes cluster lifecycle
Creates or deletes clusters based on a config definition
# examples/kube-test-do-lon1.yaml
version: 1
name: test-do-lon1
provider: digitalocean
+ status: UP
- status: DOWN
digitalocean:
cluster:
count: 1
region: lon1
size: s-1vcpu-2gb
Example
- name: Provision
uses: hckops/actions/kube-do-action@main
with:
access-token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
config-path: examples/kube-test-do-lon1.yaml
wait: true
Requires DIGITALOCEAN_ACCESS_TOKEN
secret
How to test it locally
# build image
docker build -t hckops/kube-do-action ./kube-do-action
# run action
docker run --rm \
-e GITHUB_REPOSITORY="INVALID_GITHUB_REPOSITORY" \
-e GITHUB_OUTPUT="INVALID_GITHUB_OUTPUT" \
-v ${PWD}/examples:/examples \
hckops/kube-do-action \
"INVALID_GITHUB_TOKEN" \
"INVALID_ACCESS_TOKEN" \
"./examples/kube-test-do-lon1.yaml" \
"main" \
"true" \
"false" \
"false"
TODOs
- replace implementation with Terraform?
Bootstraps a platform with ArgoCD
Example
- name: Bootstrap
uses: hckops/actions/bootstrap-action@main
with:
argocd-admin-password: ${{ secrets.ARGOCD_ADMIN_PASSWORD }}
argocd-git-ssh-key: ${{ secrets.ARGOCD_GIT_SSH_KEY }}
kubeconfig: <REPOSITORY_NAME>-kubeconfig.yaml
chart-path: ./charts/argocd-config
Requires
ARGOCD_ADMIN_PASSWORD
secretdocker run --rm -it python:3-alpine ash pip3 install bcrypt # create secret with bcrypt hash python3 -c "import bcrypt; print(bcrypt.hashpw(b'<MY-PASSWORD>', bcrypt.gensalt()).decode())"
ARGOCD_GIT_SSH_KEY
secret# generate ssh key pair ssh-keygen -t ed25519 -C "[email protected]" -N '' -f /tmp/id_ed25519_argocd # add public key to a github user account with access to the repo cat /tmp/id_ed25519_argocd.pub | xclip -selection clipboard # create secret with private key cat /tmp/id_ed25519_argocd | xclip -selection clipboard # cleanup rm /tmp/id_ed25519_argocd*
How to test it locally on minikube
# see "scripts/local.sh"
make bootstrap
# default cluster
make bootstrap kube="template"
# admin|argocd
kubectl port-forward svc/argocd-server -n argocd 8080:443
Initializes operator's master Secret
Supports
Example
# AKEYLESS
- name: Secrets
uses: hckops/actions/kube-secrets-action@main
with:
kubeconfig: <REPOSITORY_NAME>-kubeconfig.yaml
operator: external-secrets-akeyless
external-secrets-akeyless-access-id: ${{ secrets.AKEYLESS_ACCESS_ID }}
external-secrets-akeyless-access-type: api_key
external-secrets-akeyless-access-type-param: ${{ secrets.AKEYLESS_ACCESS_KEY }}
# LASTPASS
- name: Secrets
uses: hckops/actions/kube-secrets-action@main
with:
kubeconfig: <REPOSITORY_NAME>-kubeconfig.yaml
operator: edgelevel-lastpass
edgelevel-lastpass-username: ${{ secrets.LASTPASS_USERNAME }}
edgelevel-lastpass-password: ${{ secrets.LASTPASS_PASSWORD }}
Requires
AKEYLESS_ACCESS_ID
andAKEYLESS_ACCESS_KEY
secrets for Akeyless- In Auth Methods, create new API Key e.g.
kube-template-action
- In Access Roles, create new Role e.g.
template-role
, Associate Auth Method to the api key previously created and Add Rule for Secrets & Keys
# returns AKEYLESS_ACCESS_TOKEN curl --request POST \ --url https://api.akeyless.io/auth \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data '{"access-type": "access_key", "access-id": "<AKEYLESS_ACCESS_ID>", "access-key": "<AKEYLESS_ACCESS_KEY>"}' # verify access rules curl --request POST \ --url https://api.akeyless.io/get-secret-value \ --header 'accept: application/json' \ --header 'content-type: application/json' \ --data '{"names": ["/path/to/MY_SECRET"], "token": "<AKEYLESS_ACCESS_TOKEN>"}'
- In Auth Methods, create new API Key e.g.
LASTPASS_USERNAME
andLASTPASS_PASSWORD
secrets for LastPass
Keeps Helm dependencies up to date
See also dependabot/dependabot-core#2237
Example
# workflow example
- name: Helm Dependencies
uses: hckops/actions/helm-dependencies-action@main
with:
user-email: "<EMAIL>"
user-name: "<USERNAME>"
config-path: examples/dependencies.yaml
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# config example
dependencies:
# it will fetch the latest dependency from https://artifacthub.io/packages/helm/argo/argo-cd
# and create a pr with the updated version using jq/yq path in Chart.yaml
- name: "Argo CD"
source:
file: examples/test-chart/Chart.yaml
path: .dependencies[0].version
repository:
type: artifacthub
name: argo/argo-cd
For more example see
How to test it locally, sample output
# build image
docker build -t hckops/helm-dependencies-action ./helm-dependencies-action
# dry run without creating a pr
docker run --rm \
--env GITHUB_TOKEN=INVALID_TOKEN \
--env GITHUB_REPOSITORY=INVALID_REPOSITORY \
--env GITHUB_SHA=INVALID_SHA \
--volume ${PWD}/examples:/examples \
hckops/helm-dependencies-action \
"examples/dependencies.yaml" \
"INVALID_EMAIL" \
"INVALID_USERNAME" \
"main" \
"true"
- Automatically delete branches, see
https://github.com/<OWNER>/<REPOSITORY>/settings
- Suggest to update branches, see
https://github.com/<OWNER>/<REPOSITORY>/settings
- Favour squashed PRs to keep a clean commit history, see
https://github.com/<OWNER>/<REPOSITORY>/settings
- Enable default branch protection, see
https://github.com/<OWNER>/<REPOSITORY>/settings/branches
. The action pushes a status check namedaction/helm-dependencies
upon success
- If you get the following error, pull request create failed: GraphQL: GitHub Actions is not permitted to create or approve pull requests (createPullRequest)
- make sure you've enabled
Allow GitHub Actions to create and approve pull requests
in your organization and repository settings https://github.com/organizations/<ORGANIZATION>/settings/actions
https://github.com/<OWNER>/<REPOSITORY>/settings/actions
- make sure you've enabled
Validates Helm charts
Example
- name: Helm Lint
uses: hckops/actions/helm-lint-action@main
TODOs
- rename to
kube-validate
- add https://github.com/yannh/kubeconform
- add https://github.com/koalaman/shellcheck
Interacts with Discord API
Example of Create message
- name: Notification
uses: hckops/actions/discord-action@main
with:
action: create-message
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
message: "Hello World"
Requires DISCORD_WEBHOOK_URL
secret
How to test it locally
DISCORD_WEBHOOK_URL="INVALID_URL"
make discord-create webhook=${DISCORD_WEBHOOK_URL} message=test
docker build -t hckops/discord-action ./discord-action
docker run --rm hckops/discord-action "create-message" ${DISCORD_WEBHOOK_URL} "docker"
Builds and publishes Docker images
See composite actions, useful to build base images in combination with matrixes
- name: Docker CI
uses: hckops/actions/docker-template-action@main
with:
DOCKER_CONTEXT: "./docker/<IMAGE_NAME>"
# optional
DOCKER_FILE: "Dockerfile"
DOCKER_IMAGE_NAME: "<IMAGE_NAME>"
DOCKER_REPOSITORY: "<REPOSITORY_NAME>"
# optional, default is sha
DOCKER_DEFAULT_TAG: "latest"
SECRET_DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
SECRET_DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
# optional
SECRET_DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
Action's base images
# run command
docker run --rm hckops/kube-base /bin/bash -c <kubectl|helm>
# start temporary container
docker run --rm --name hck-tmp -it hckops/kube-<base|argo|aws|do>
How to publish docker images
# list latest tags
curl -sS "https://api.github.com/repos/hckops/actions/tags" | jq '.[].name'
# publish with action
git tag docker-X.Y.Z
git push origin --tags
# build and publish manually (old)
make docker-build
make docker-publish version=vX.Y.Z token=<ACCESS_TOKEN>
make docker-clean
Actions to update when a new docker tag is created
bootstrap-action
helm-dependencies-action
helm-lint-action
kube-do-action
kube-secrets-action
# bump all images
make update-version old="<OLD_VERSION>" new="<NEW_VERSION>"
# install
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb
sudo dpkg -i minikube_latest_amd64.deb
# local cluster
minikube start --driver=docker --embed-certs
minikube delete --all
# verify status
kubectl get nodes