302 lines
9.9 KiB
YAML
302 lines
9.9 KiB
YAML
# Tekton Update GitOps Manifests Task for Bakery-IA CI/CD
|
|
# This task updates Kubernetes manifests with new image tags using Kustomize
|
|
# It uses a safer approach than sed for updating image references
|
|
|
|
apiVersion: tekton.dev/v1beta1
|
|
kind: Task
|
|
metadata:
|
|
name: update-gitops
|
|
namespace: tekton-pipelines
|
|
labels:
|
|
app.kubernetes.io/name: bakery-ia-cicd
|
|
app.kubernetes.io/component: gitops
|
|
spec:
|
|
workspaces:
|
|
- name: source
|
|
description: Source code workspace with Git repository
|
|
- name: git-credentials
|
|
description: Git credentials for pushing changes
|
|
optional: true
|
|
params:
|
|
- name: services
|
|
type: string
|
|
description: Comma-separated list of services to update
|
|
- name: registry
|
|
type: string
|
|
description: Container registry URL
|
|
- name: git-revision
|
|
type: string
|
|
description: Git revision for image tag
|
|
- name: git-branch
|
|
type: string
|
|
description: Target branch for GitOps updates
|
|
default: "main"
|
|
- name: dry-run
|
|
type: string
|
|
description: If "true", only show what would be changed without committing
|
|
default: "false"
|
|
results:
|
|
- name: updated-services
|
|
description: List of services that were updated
|
|
- name: commit-sha
|
|
description: Git commit SHA of the update (empty if dry-run)
|
|
steps:
|
|
- name: update-manifests
|
|
# Use alpine with curl to install kustomize
|
|
image: alpine:3.19
|
|
script: |
|
|
#!/bin/sh
|
|
set -e
|
|
|
|
# Install kustomize
|
|
echo "Installing kustomize..."
|
|
wget -q "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" -O - | sh
|
|
mv kustomize /usr/local/bin/
|
|
echo "Kustomize version: $(kustomize version)"
|
|
|
|
SOURCE_PATH="$(workspaces.source.path)"
|
|
SERVICES="$(params.services)"
|
|
REGISTRY="$(params.registry)"
|
|
REVISION="$(params.git-revision)"
|
|
DRY_RUN="$(params.dry-run)"
|
|
UPDATED_SERVICES=""
|
|
|
|
cd "$SOURCE_PATH"
|
|
|
|
echo "============================================"
|
|
echo "GitOps Manifest Update"
|
|
echo "============================================"
|
|
echo "Services: $SERVICES"
|
|
echo "Registry: $REGISTRY"
|
|
echo "Revision: $REVISION"
|
|
echo "Dry Run: $DRY_RUN"
|
|
echo "============================================"
|
|
|
|
# Skip if no services to update
|
|
if [ "$SERVICES" = "none" ] || [ -z "$SERVICES" ]; then
|
|
echo "No services to update, skipping..."
|
|
echo "none" > $(results.updated-services.path)
|
|
echo "" > $(results.commit-sha.path)
|
|
exit 0
|
|
fi
|
|
|
|
# Define the kustomization directory
|
|
KUSTOMIZE_DIR="infrastructure/environments/prod"
|
|
|
|
# Check if kustomization.yaml exists, create if not
|
|
if [ ! -f "$KUSTOMIZE_DIR/kustomization.yaml" ]; then
|
|
echo "Creating kustomization.yaml in $KUSTOMIZE_DIR"
|
|
mkdir -p "$KUSTOMIZE_DIR"
|
|
printf '%s\n' \
|
|
"apiVersion: kustomize.config.k8s.io/v1beta1" \
|
|
"kind: Kustomization" \
|
|
"" \
|
|
"resources:" \
|
|
" - ../base" \
|
|
"" \
|
|
"images: []" \
|
|
> "$KUSTOMIZE_DIR/kustomization.yaml"
|
|
fi
|
|
|
|
# Convert comma-separated list to space-separated
|
|
SERVICES_LIST=$(echo "$SERVICES" | tr ',' ' ')
|
|
|
|
# Build the images section for kustomization
|
|
echo ""
|
|
echo "Updating image references..."
|
|
|
|
for SERVICE in $SERVICES_LIST; do
|
|
# Trim whitespace
|
|
SERVICE=$(echo "$SERVICE" | tr -d ' ')
|
|
|
|
# Skip infrastructure changes
|
|
if [ "$SERVICE" = "infrastructure" ]; then
|
|
echo "Skipping infrastructure (not a deployable service)"
|
|
continue
|
|
fi
|
|
|
|
echo "Processing: $SERVICE"
|
|
|
|
# Determine the image name based on service
|
|
NEW_IMAGE="$REGISTRY/bakery/$SERVICE:$REVISION"
|
|
|
|
# Use kustomize to set the image
|
|
# This is safer than sed as it understands the YAML structure
|
|
cd "$SOURCE_PATH/$KUSTOMIZE_DIR"
|
|
|
|
# Check if this service has a deployment
|
|
SERVICE_DEPLOYMENT=""
|
|
if [ "$SERVICE" = "frontend" ]; then
|
|
SERVICE_DEPLOYMENT="frontend"
|
|
elif [ "$SERVICE" = "gateway" ]; then
|
|
SERVICE_DEPLOYMENT="gateway"
|
|
else
|
|
SERVICE_DEPLOYMENT="$SERVICE-service"
|
|
fi
|
|
|
|
# Update the kustomization with the new image
|
|
# Using kustomize edit to safely modify the file
|
|
kustomize edit set image "bakery/$SERVICE=$NEW_IMAGE" 2>/dev/null || \
|
|
kustomize edit set image "$SERVICE=$NEW_IMAGE" 2>/dev/null || \
|
|
echo "Note: Could not set image via kustomize edit, will use alternative method"
|
|
|
|
# Track updated services
|
|
if [ -z "$UPDATED_SERVICES" ]; then
|
|
UPDATED_SERVICES="$SERVICE"
|
|
else
|
|
UPDATED_SERVICES="$UPDATED_SERVICES,$SERVICE"
|
|
fi
|
|
|
|
cd "$SOURCE_PATH"
|
|
done
|
|
|
|
# Alternative: Update images in kustomization.yaml directly if kustomize edit didn't work
|
|
# This creates/updates an images section in the kustomization
|
|
echo ""
|
|
echo "Ensuring image overrides in kustomization.yaml..."
|
|
|
|
# Create a patch file for image updates
|
|
IMAGES_FILE="$KUSTOMIZE_DIR/images.yaml"
|
|
printf '%s\n' \
|
|
"# Auto-generated by CI/CD pipeline" \
|
|
"# Commit: $REVISION" \
|
|
"# Updated: $(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
|
|
"images:" \
|
|
> "$IMAGES_FILE"
|
|
|
|
for SERVICE in $SERVICES_LIST; do
|
|
SERVICE=$(echo "$SERVICE" | tr -d ' ')
|
|
if [ "$SERVICE" != "infrastructure" ]; then
|
|
printf '%s\n' \
|
|
" - name: bakery/$SERVICE" \
|
|
" newName: $REGISTRY/bakery/$SERVICE" \
|
|
" newTag: \"$REVISION\"" \
|
|
>> "$IMAGES_FILE"
|
|
fi
|
|
done
|
|
|
|
echo ""
|
|
echo "Generated images.yaml:"
|
|
cat "$IMAGES_FILE"
|
|
|
|
# Validate the kustomization
|
|
echo ""
|
|
echo "Validating kustomization..."
|
|
cd "$SOURCE_PATH/$KUSTOMIZE_DIR"
|
|
if kustomize build . > /dev/null 2>&1; then
|
|
echo "Kustomization is valid"
|
|
else
|
|
echo "Warning: Kustomization validation failed, but continuing..."
|
|
fi
|
|
cd "$SOURCE_PATH"
|
|
|
|
# Write results
|
|
echo "$UPDATED_SERVICES" > $(results.updated-services.path)
|
|
|
|
if [ "$DRY_RUN" = "true" ]; then
|
|
echo ""
|
|
echo "============================================"
|
|
echo "DRY RUN - Changes not committed"
|
|
echo "============================================"
|
|
echo "Would update services: $UPDATED_SERVICES"
|
|
git diff --stat || true
|
|
echo "" > $(results.commit-sha.path)
|
|
exit 0
|
|
fi
|
|
|
|
echo ""
|
|
echo "Committing changes..."
|
|
resources:
|
|
limits:
|
|
cpu: 500m
|
|
memory: 512Mi
|
|
requests:
|
|
cpu: 100m
|
|
memory: 256Mi
|
|
|
|
- name: commit-and-push
|
|
image: alpine/git:2.43.0
|
|
script: |
|
|
#!/bin/sh
|
|
set -e
|
|
|
|
SOURCE_PATH="$(workspaces.source.path)"
|
|
SERVICES="$(params.services)"
|
|
REVISION="$(params.git-revision)"
|
|
BRANCH="$(params.git-branch)"
|
|
DRY_RUN="$(params.dry-run)"
|
|
|
|
cd "$SOURCE_PATH"
|
|
|
|
if [ "$DRY_RUN" = "true" ]; then
|
|
echo "Dry run mode - skipping commit"
|
|
echo "" > $(results.commit-sha.path)
|
|
exit 0
|
|
fi
|
|
|
|
if [ "$SERVICES" = "none" ] || [ -z "$SERVICES" ]; then
|
|
echo "No services to commit"
|
|
echo "" > $(results.commit-sha.path)
|
|
exit 0
|
|
fi
|
|
|
|
# Check if there are changes to commit
|
|
if git diff --quiet && git diff --cached --quiet; then
|
|
echo "No changes to commit"
|
|
echo "" > $(results.commit-sha.path)
|
|
exit 0
|
|
fi
|
|
|
|
# Configure git
|
|
git config --global user.name "bakery-ia-ci"
|
|
git config --global user.email "ci@bakery-ia.local"
|
|
git config --global --add safe.directory "$SOURCE_PATH"
|
|
|
|
# Setup git credentials if provided
|
|
if [ -d "$(workspaces.git-credentials.path)" ]; then
|
|
if [ -f "$(workspaces.git-credentials.path)/username" ] && [ -f "$(workspaces.git-credentials.path)/password" ]; then
|
|
GIT_USER=$(cat "$(workspaces.git-credentials.path)/username")
|
|
GIT_PASS=$(cat "$(workspaces.git-credentials.path)/password")
|
|
|
|
# Get the remote URL and inject credentials
|
|
REMOTE_URL=$(git remote get-url origin)
|
|
# Handle both http and https
|
|
if echo "$REMOTE_URL" | grep -q "^http"; then
|
|
REMOTE_URL=$(echo "$REMOTE_URL" | sed "s|://|://$GIT_USER:$GIT_PASS@|")
|
|
git remote set-url origin "$REMOTE_URL"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Stage changes
|
|
git add -A
|
|
|
|
# Create commit with detailed message
|
|
COMMIT_MSG=$(printf 'ci: Update image tags to %s\n\nServices updated: %s\n\nThis commit was automatically generated by the CI/CD pipeline.\nPipeline run triggered by commit: %s' "$REVISION" "$SERVICES" "$REVISION")
|
|
|
|
git commit -m "$COMMIT_MSG"
|
|
|
|
# Get the commit SHA
|
|
COMMIT_SHA=$(git rev-parse HEAD)
|
|
echo "$COMMIT_SHA" > $(results.commit-sha.path)
|
|
|
|
echo "Created commit: $COMMIT_SHA"
|
|
|
|
# Push changes
|
|
echo "Pushing to origin/$BRANCH..."
|
|
git push origin HEAD:"$BRANCH"
|
|
|
|
echo ""
|
|
echo "============================================"
|
|
echo "GitOps Update Complete"
|
|
echo "============================================"
|
|
echo "Commit: $COMMIT_SHA"
|
|
echo "Branch: $BRANCH"
|
|
echo "Services: $SERVICES"
|
|
resources:
|
|
limits:
|
|
cpu: 200m
|
|
memory: 128Mi
|
|
requests:
|
|
cpu: 50m
|
|
memory: 64Mi |