Skip to content

Commit b84e42b

Browse files
Add support to create new base toolkit image, to package up commonly use tools such as awscli, jq etc. (#554)
* feat: add base toolkit image builder using github actions * fix: paths to Dockerfile * fix: rename base image * fix: image name for custom naming scheme * feat: move to matrix strategy * fix: remove get_versions.sh
1 parent ea9c3b8 commit b84e42b

File tree

3 files changed

+263
-0
lines changed

3 files changed

+263
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
name: Create and publish toolkit base image
2+
3+
on:
4+
workflow_dispatch:
5+
6+
env:
7+
REGISTRY: ghcr.io
8+
IMAGE_NAME: ${{ github.repository_owner }}/eks-toolkit-base
9+
BUILD_CONTEXT: tests/images/toolkit-base/
10+
11+
jobs:
12+
get_versions_job:
13+
runs-on: ubuntu-latest
14+
outputs:
15+
k8s_versions: ${{ steps.determine_versions.outputs.k8s_versions }}
16+
latest_tools: ${{ steps.determine_versions.outputs.latest_tools }}
17+
18+
steps:
19+
- name: Checkout repository
20+
uses: actions/checkout@v4
21+
- name: Install jq
22+
run: sudo apt-get update && sudo apt-get install -y jq
23+
24+
- name: Determine K8s Versions and Tool Versions
25+
id: determine_versions
26+
working-directory: ${{ env.BUILD_CONTEXT }}
27+
run: |
28+
chmod +x ./get_versions_matrix.sh # We need a new version of the script
29+
./get_versions_matrix.sh
30+
31+
build_and_push_image:
32+
needs: get_versions_job
33+
runs-on: ubuntu-latest
34+
permissions:
35+
contents: read
36+
packages: write
37+
attestations: write
38+
id-token: write
39+
40+
strategy:
41+
fail-fast: false # Optional: Set to false if you want other builds to finish even if one fails
42+
matrix:
43+
k8s_tag: ${{ fromJson(needs.get_versions_job.outputs.k8s_versions) }}
44+
steps:
45+
- name: Checkout repository
46+
uses: actions/checkout@v4
47+
48+
- name: Setup QEMU
49+
uses: docker/setup-qemu-action@v3
50+
51+
- name: Setup docker buildx
52+
uses: docker/setup-buildx-action@v3
53+
54+
- name: Log in to the Container registry
55+
uses: docker/login-action@v3
56+
with:
57+
registry: ${{ env.REGISTRY }}
58+
username: ${{ github.actor }}
59+
password: ${{ secrets.GITHUB_TOKEN }}
60+
61+
- name: Set Image Tag for Matrix Run
62+
id: tags
63+
run: |
64+
# Use the K8s version as the primary tag
65+
echo "tag=${{ matrix.k8s_tag }}" >> $GITHUB_OUTPUT
66+
67+
- name: Build and push Docker image
68+
uses: docker/build-push-action@v6
69+
with:
70+
context: ${{ env.BUILD_CONTEXT }}
71+
platforms: linux/amd64,linux/arm64
72+
push: true
73+
# The tags are set dynamically by the 'Set Image Tag' step
74+
tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ matrix.k8s_tag }}
75+
76+
# Extract the static tool versions from the needs output
77+
build-args: |
78+
KUBECTL_VERSION=${{ matrix.k8s_tag }}
79+
HELM_VERSION=${{ fromJson(needs.get_versions_job.outputs.latest_tools).helm_version }}
80+
KUSTOMIZE_VERSION=${{ fromJson(needs.get_versions_job.outputs.latest_tools).kustomize_version }}
81+
KUBESEAL_VERSION=${{ fromJson(needs.get_versions_job.outputs.latest_tools).kubeseal_version }}
82+
KREW_VERSION=${{ fromJson(needs.get_versions_job.outputs.latest_tools).krew_version }}
83+
VALS_VERSION=${{ fromJson(needs.get_versions_job.outputs.latest_tools).vals_version }}
84+
KUBECONFORM_VERSION=${{ fromJson(needs.get_versions_job.outputs.latest_tools).kubeconform_version }}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
FROM alpine
2+
3+
ARG ARCH
4+
5+
# Ignore to update versions here
6+
# docker build --no-cache --build-arg KUBECTL_VERSION=${tag} --build-arg HELM_VERSION=${helm} --build-arg KUSTOMIZE_VERSION=${kustomize_version} -t ${image}:${tag} .
7+
ARG HELM_VERSION=3.2.1
8+
ARG KUBECTL_VERSION=1.17.5
9+
ARG KUSTOMIZE_VERSION=v3.8.1
10+
ARG KUBESEAL_VERSION=0.18.1
11+
ARG KREW_VERSION=v0.4.4
12+
ARG VALS_VERSION=0.28.1
13+
ARG KUBECONFORM_VERSION=0.6.3
14+
15+
# Install helm (latest release)
16+
# ENV BASE_URL="https://storage.googleapis.com/kubernetes-helm"
17+
RUN case `uname -m` in \
18+
x86_64) ARCH=amd64; ;; \
19+
armv7l) ARCH=arm; ;; \
20+
aarch64) ARCH=arm64; ;; \
21+
ppc64le) ARCH=ppc64le; ;; \
22+
s390x) ARCH=s390x; ;; \
23+
*) echo "un-supported arch, exit ..."; exit 1; ;; \
24+
esac && \
25+
echo "export ARCH=$ARCH" > /envfile && \
26+
cat /envfile
27+
28+
RUN . /envfile && echo $ARCH && \
29+
apk add --update --no-cache curl ca-certificates bash git && \
30+
curl -sL https://get.helm.sh/helm-v${HELM_VERSION}-linux-${ARCH}.tar.gz | tar -xvz && \
31+
mv linux-${ARCH}/helm /usr/bin/helm && \
32+
chmod +x /usr/bin/helm && \
33+
rm -rf linux-${ARCH}
34+
35+
# add helm-diff
36+
RUN helm plugin install https://github.com/databus23/helm-diff --verify=false && rm -rf /tmp/helm-* && \
37+
rm -rf ~/.cache/helm/plugins/https-github.com-databus23-helm-diff/.git
38+
39+
# add helm-unittest
40+
RUN helm plugin install https://github.com/helm-unittest/helm-unittest --verify=false && rm -rf /tmp/helm-*
41+
42+
# add helm-push
43+
RUN helm plugin install https://github.com/chartmuseum/helm-push --verify=false && \
44+
rm -rf /tmp/helm-* \
45+
/root/.local/share/helm/plugins/helm-push/testdata \
46+
/root/.cache/helm/plugins/https-github.com-chartmuseum-helm-push/testdata
47+
48+
# Install kubectl
49+
RUN . /envfile && echo $ARCH && \
50+
curl -sLO "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/${ARCH}/kubectl" && \
51+
mv kubectl /usr/bin/kubectl && \
52+
chmod +x /usr/bin/kubectl
53+
54+
# Install kustomize (latest release)
55+
RUN . /envfile && echo $ARCH && \
56+
curl -sLO https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2F${KUSTOMIZE_VERSION}/kustomize_${KUSTOMIZE_VERSION}_linux_${ARCH}.tar.gz && \
57+
tar xvzf kustomize_${KUSTOMIZE_VERSION}_linux_${ARCH}.tar.gz && \
58+
mv kustomize /usr/bin/kustomize && \
59+
chmod +x /usr/bin/kustomize && \
60+
rm kustomize_${KUSTOMIZE_VERSION}_linux_${ARCH}.tar.gz
61+
62+
# Install eksctl (latest version)
63+
RUN . /envfile && echo $ARCH && \
64+
curl -sL "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_${ARCH}.tar.gz" | tar xz -C /tmp && \
65+
mv /tmp/eksctl /usr/bin && \
66+
chmod +x /usr/bin/eksctl
67+
68+
# Install awscli
69+
# Temp fix to allow system-wide package installation:
70+
# https://stackoverflow.com/a/76540031/3671801
71+
RUN apk add --update --no-cache py3-pip && \
72+
pip3 install --break-system-packages --upgrade pip setuptools && \
73+
pip3 install --break-system-packages awscli && \
74+
pip3 cache purge
75+
76+
# Install jq
77+
RUN apk add --update --no-cache jq yq
78+
79+
# https://docs.aws.amazon.com/eks/latest/userguide/install-aws-iam-authenticator.html
80+
# Install aws-iam-authenticator (latest version)
81+
RUN . /envfile && echo $ARCH && \
82+
authenticator=$(curl -fs https://api.github.com/repos/kubernetes-sigs/aws-iam-authenticator/releases/latest | jq --raw-output '.name' | sed 's/^v//') && \
83+
curl -fL https://github.com/kubernetes-sigs/aws-iam-authenticator/releases/download/v${authenticator}/aws-iam-authenticator_${authenticator}_linux_${ARCH} -o /usr/bin/aws-iam-authenticator && \
84+
chmod +x /usr/bin/aws-iam-authenticator
85+
86+
# Install for envsubst
87+
RUN apk add --update --no-cache gettext
88+
89+
# Install kubeseal
90+
RUN . /envfile && echo $ARCH && \
91+
curl -L https://github.com/bitnami-labs/sealed-secrets/releases/download/v${KUBESEAL_VERSION}/kubeseal-${KUBESEAL_VERSION}-linux-${ARCH}.tar.gz -o - | tar xz -C /usr/bin/ && \
92+
chmod +x /usr/bin/kubeseal
93+
94+
# Install vals
95+
RUN . /envfile && echo $ARCH && \
96+
curl -L https://github.com/helmfile/vals/releases/download/v${VALS_VERSION}/vals_${VALS_VERSION}_linux_${ARCH}.tar.gz -o -| tar xz -C /usr/bin/ && \
97+
chmod +x /usr/bin/vals
98+
99+
# Install krew (latest release)
100+
RUN . /envfile && echo $ARCH && \
101+
curl -fsSLO "https://github.com/kubernetes-sigs/krew/releases/download/v${KREW_VERSION}/krew-linux_${ARCH}.tar.gz" && \
102+
tar zxvf krew-linux_${ARCH}.tar.gz && \
103+
./krew-linux_${ARCH} install krew && \
104+
echo 'export PATH=/root/.krew/bin:$PATH' >> ~/.bashrc && \
105+
rm krew-linux_${ARCH}.tar.gz
106+
107+
# Install kubeconform
108+
RUN . /envfile && echo $ARCH && \
109+
curl -L https://github.com/yannh/kubeconform/releases/download/v${KUBECONFORM_VERSION}/kubeconform-linux-${ARCH}.tar.gz -o - | tar xz -C /usr/bin/ && \
110+
chmod +x /usr/bin/kubeconform
111+
112+
WORKDIR /apps
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
# --- 1. Find all Static Tool Versions (Combined into a single JSON object) ---
6+
7+
HELM_VERSION=$(curl -s https://api.github.com/repos/helm/helm/releases | jq -r '.[].tag_name | select([startswith("v"), (contains("-") | not)] | all)' | sort -rV | head -n 1 | sed 's/v//')
8+
KUSTOMIZE_RELEASE=$(curl -s https://api.github.com/repos/kubernetes-sigs/kustomize/releases | jq -r '.[].tag_name | select(contains("kustomize"))' | sort -rV | head -n 1)
9+
KUSTOMIZE_VERSION=$(basename ${KUSTOMIZE_RELEASE})
10+
KUBESEAL_VERSION=$(curl -s https://api.github.com/repos/bitnami-labs/sealed-secrets/releases | jq -r '.[].tag_name | select(startswith("v"))' | sort -rV | head -n 1 | sed 's/v//')
11+
KREW_VERSION=$(curl -s https://api.github.com/repos/kubernetes-sigs/krew/releases | jq -r '.[].tag_name | select(startswith("v"))' | sort -rV | head -n 1 | sed 's/v//')
12+
VALS_VERSION=$(curl -s https://api.github.com/repos/helmfile/vals/releases | jq -r '.[].tag_name | select(startswith("v"))' | sort -rV | head -n 1 | sed 's/v//')
13+
KUBECONFORM_VERSION=$(curl -s https://api.github.com/repos/yannh/kubeconform/releases | jq -r '.[].tag_name | select(startswith("v"))' | sort -rV | head -n 1 | sed 's/v//')
14+
15+
16+
# Construct a single, compacted JSON object without extra spaces
17+
LATEST_TOOLS_JSON=$(
18+
jq -n -c \
19+
--arg helm "$HELM_VERSION" \
20+
--arg kustomize "$KUSTOMIZE_VERSION" \
21+
--arg kubeseal "$KUBESEAL_VERSION" \
22+
--arg krew "$KREW_VERSION" \
23+
--arg vals "$VALS_VERSION" \
24+
--arg kubeconform "$KUBECONFORM_VERSION" \
25+
'{
26+
"helm_version": $helm,
27+
"kustomize_version": $kustomize,
28+
"kubeseal_version": $kubeseal,
29+
"krew_version": $krew,
30+
"vals_version": $vals,
31+
"kubeconform_version": $kubeconform
32+
}'
33+
)
34+
35+
# Use the 'LATEST_TOOLS_JSON' variable directly, ensuring no leading spaces
36+
echo "latest_tools=$LATEST_TOOLS_JSON" >> $GITHUB_OUTPUT
37+
38+
# Optional: Keep the echo for logging, but ONLY to stdout, not GITHUB_OUTPUT
39+
echo "Found static tools: $LATEST_TOOLS_JSON"
40+
41+
42+
# --- 2. Find the top 4 latest K8s minor versions (Output as a JSON Array) ---
43+
44+
RELEASES=$(curl -s https://api.github.com/repos/kubernetes/kubernetes/releases | jq -r '.[].tag_name | select(test("alpha|beta|rc") | not)')
45+
46+
MINOR_VERSIONS=()
47+
for RELEASE in $RELEASES; do
48+
MINOR_VERSION=$(echo $RELEASE | awk -F'.' '{print $1"."$2}')
49+
if [[ ! " ${MINOR_VERSIONS[@]} " =~ " ${MINOR_VERSION} " ]]; then
50+
MINOR_VERSIONS+=($MINOR_VERSION)
51+
fi
52+
done
53+
54+
SORTED_MINOR_VERSIONS=($(echo "${MINOR_VERSIONS[@]}" | tr ' ' '\n' | sort -rV))
55+
56+
K8S_TAGS=()
57+
for i in $(seq 0 3); do
58+
MINOR_VERSION="${SORTED_MINOR_VERSIONS[$i]}"
59+
LATEST_VERSION=$(echo "$RELEASES" | grep "^$MINOR_VERSION\." | sort -rV | head -1 | sed 's/v//')
60+
K8S_TAGS+=("$LATEST_VERSION")
61+
done
62+
63+
# Convert the bash array into a single-line JSON array string (using -c flag for compact output)
64+
K8S_TAGS_JSON=$(printf '%s\n' "${K8S_TAGS[@]}" | jq -R . | jq -s -c .)
65+
66+
echo "k8s_versions=$K8S_TAGS_JSON" >> $GITHUB_OUTPUT
67+
echo "Found K8s versions: ${K8S_TAGS[*]}"

0 commit comments

Comments
 (0)