diff --git a/.github/workflows/ephemeral.yml b/.github/workflows/ephemeral.yml new file mode 100644 index 0000000..9eeba9d --- /dev/null +++ b/.github/workflows/ephemeral.yml @@ -0,0 +1,273 @@ +name: PR Ephemeral Environment + +on: + pull_request: + types: [opened, synchronize, reopened, closed] + +env: + REGISTRY: registry.fullstack.pw + IMAGE_NAME: library/cks-frontend + VAULT_ADDR: https://vault.fullstack.pw + +jobs: + manage-environment: + runs-on: self-hosted + outputs: + dns_name: ${{ steps.cluster-info.outputs.dns_name }} + cluster_name: ${{ steps.cluster-info.outputs.cluster_name }} + deployment_status: ${{ steps.deployment-status.outputs.status }} + steps: + - name: Set cluster info + id: cluster-info + run: | + CLUSTER_NAME="pr-${{ github.event.repository.name }}-${{ github.event.pull_request.number }}" + DNS_NAME="pr-${{ github.event.pull_request.number }}-${{ github.event.repository.name }}.ephemeral.fullstack.pw" + echo "cluster_name=$CLUSTER_NAME" >> $GITHUB_OUTPUT + echo "dns_name=$DNS_NAME" >> $GITHUB_OUTPUT + + - name: Checkout infra repo + uses: actions/checkout@v4 + with: + repository: fullstack-pw/infra + token: ${{ secrets.RUNNER }} + path: infra + + - name: Check if cluster exists + id: check-cluster + run: | + CLUSTER_NAME="${{ steps.cluster-info.outputs.cluster_name }}" + if kubectl get cluster "$CLUSTER_NAME" -n "$CLUSTER_NAME" --context tools --kubeconfig /home/runner/.kube/config &>/dev/null; then + echo "exists=true" >> $GITHUB_OUTPUT + echo "Cluster $CLUSTER_NAME already exists" + else + echo "exists=false" >> $GITHUB_OUTPUT + echo "Cluster $CLUSTER_NAME does not exist" + fi + + # ==================== CREATE/UPDATE ENVIRONMENT ==================== + - name: Check IP pool capacity + if: github.event.action != 'closed' && steps.check-cluster.outputs.exists == 'false' + run: | + cd infra + AVAILABLE=$(./clusters/scripts/ip_pool_manager.sh check-capacity) + CAPACITY_RESULT=$? + echo "Capacity available: $AVAILABLE slots free" + if [ "$CAPACITY_RESULT" -ne 0 ]; then + echo "::error::IP pool exhausted. All 5 ephemeral cluster slots are in use (10 IPs / 2 per cluster). Please close old PRs." + exit 1 + fi + + - name: Allocate IP from pool + if: github.event.action != 'closed' && steps.check-cluster.outputs.exists == 'false' + id: allocate + run: | + cd infra + CLUSTER_NAME="${{ steps.cluster-info.outputs.cluster_name }}" + CLUSTER_IP=$(./clusters/scripts/ip_pool_manager.sh allocate "$CLUSTER_NAME") + + # Calculate node IP (VIP + 1) - each cluster needs 2 IPs + IP_LAST_OCTET=$(echo "$CLUSTER_IP" | cut -d'.' -f4) + NODE_IP_LAST_OCTET=$((IP_LAST_OCTET + 1)) + NODE_IP="192.168.1.${NODE_IP_LAST_OCTET}" + + echo "ip=$CLUSTER_IP" >> $GITHUB_OUTPUT + echo "node_ip=$NODE_IP" >> $GITHUB_OUTPUT + echo "Allocated control plane VIP: $CLUSTER_IP" + echo "Node IP: $NODE_IP" + + - name: Render Cluster API manifest + if: github.event.action != 'closed' && steps.check-cluster.outputs.exists == 'false' + run: | + cd infra + export CLUSTER_NAME="${{ steps.cluster-info.outputs.cluster_name }}" + export CLUSTER_IP="${{ steps.allocate.outputs.ip }}" + export NODE_IP="${{ steps.allocate.outputs.node_ip }}" + export PR_NUMBER="${{ github.event.pull_request.number }}" + export REPOSITORY="${{ github.event.repository.name }}" + envsubst < ephemeral-clusters/cluster-api/k3s-cluster.yaml.tpl > /tmp/cluster.yaml + cat /tmp/cluster.yaml + + - name: Create cluster via Cluster API + if: github.event.action != 'closed' && steps.check-cluster.outputs.exists == 'false' + run: | + kubectl apply -f /tmp/cluster.yaml --context tools --kubeconfig /home/runner/.kube/config + + - name: Copy Proxmox credentials to namespace + if: github.event.action != 'closed' && steps.check-cluster.outputs.exists == 'false' + run: | + CLUSTER_NAME="${{ steps.cluster-info.outputs.cluster_name }}" + kubectl --context tools --kubeconfig /home/runner/.kube/config \ + get secret proxmox-credentials -n k3s-test -o json | \ + jq 'del(.metadata.namespace,.metadata.uid,.metadata.resourceVersion,.metadata.creationTimestamp,.metadata.ownerReferences,.metadata.finalizers)' | \ + kubectl --context tools --kubeconfig /home/runner/.kube/config apply -n "$CLUSTER_NAME" -f - || \ + echo "Warning: Could not copy proxmox-credentials (may already exist)" + + - name: Wait for cluster available + if: github.event.action != 'closed' && steps.check-cluster.outputs.exists == 'false' + run: | + CLUSTER_NAME="${{ steps.cluster-info.outputs.cluster_name }}" + echo "Waiting for cluster $CLUSTER_NAME to be available..." + kubectl wait --for=condition=Available \ + cluster/$CLUSTER_NAME \ + -n $CLUSTER_NAME \ + --timeout=5m --context tools --kubeconfig /home/runner/.kube/config + + - name: Extract kubeconfig + if: github.event.action != 'closed' && steps.check-cluster.outputs.exists == 'false' + run: | + CLUSTER_NAME="${{ steps.cluster-info.outputs.cluster_name }}" + kubectl get secret ${CLUSTER_NAME}-kubeconfig \ + -n $CLUSTER_NAME \ + -o jsonpath='{.data.value}' --context tools --kubeconfig /home/runner/.kube/config | base64 -d > /tmp/kubeconfig + + # Rename context to match workspace name for OpenTofu + ORIGINAL_CONTEXT=$(kubectl --kubeconfig /tmp/kubeconfig config current-context) + kubectl --kubeconfig /tmp/kubeconfig config rename-context "$ORIGINAL_CONTEXT" "$CLUSTER_NAME" + kubectl --kubeconfig /tmp/kubeconfig config use-context "$CLUSTER_NAME" + + - name: Apply ephemeral infrastructure with OpenTofu + if: github.event.action != 'closed' && steps.check-cluster.outputs.exists == 'false' + env: + KUBECONFIG: /tmp/kubeconfig + run: | + cd infra + make ephemeral-init + make ephemeral-apply WORKSPACE=${{ steps.cluster-info.outputs.cluster_name }} MINIMAL=true + + # ==================== BUILD AND DEPLOY (PR opened/updated) ==================== + - name: Checkout app code + if: github.event.action != 'closed' + uses: actions/checkout@v4 + + - name: Build and push Docker image + if: github.event.action != 'closed' + run: | + docker build -t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:pr-${{ github.event.pull_request.number }} . + echo "${HARBOR_KEY}" | docker login ${{ env.REGISTRY }} -u admin --password-stdin + docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:pr-${{ github.event.pull_request.number }} + + - name: Extract kubeconfig + if: github.event.action != 'closed' + run: | + CLUSTER_NAME="${{ steps.cluster-info.outputs.cluster_name }}" + kubectl get secret ${CLUSTER_NAME}-kubeconfig \ + -n $CLUSTER_NAME \ + -o jsonpath='{.data.value}' --context tools --kubeconfig /home/runner/.kube/config | base64 -d > /tmp/kubeconfig + + # Rename context to match workspace name for OpenTofu + ORIGINAL_CONTEXT=$(kubectl --kubeconfig /tmp/kubeconfig config current-context) + kubectl --kubeconfig /tmp/kubeconfig config rename-context "$ORIGINAL_CONTEXT" "$CLUSTER_NAME" + kubectl --kubeconfig /tmp/kubeconfig config use-context "$CLUSTER_NAME" + + - name: Deploy to ephemeral cluster + if: github.event.action != 'closed' + env: + KUBECONFIG: /tmp/kubeconfig + run: | + DNS_NAME="${{ steps.cluster-info.outputs.dns_name }}" + + # Render manifests with updated image tag and DNS hostname + kubectl kustomize kustomize/overlays/ephemeral \ + | sed "s|${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:pr-will-be-replaced|${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:pr-${{ github.event.pull_request.number }}|" \ + | sed "s|dev.cks.fullstack.pw|${DNS_NAME}|g" \ + | kubectl apply -f - + + # Wait for deployment rollout + kubectl rollout status deployment/cks-frontend \ + -n default --timeout=5m + + - name: Set deployment status + id: deployment-status + if: github.event.action != 'closed' + run: echo "status=success" >> $GITHUB_OUTPUT + + - name: Post deployment info + if: github.event.action != 'closed' && steps.check-cluster.outputs.exists == 'false' + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + const dnsName = '${{ steps.cluster-info.outputs.dns_name }}'; + const clusterName = '${{ steps.cluster-info.outputs.cluster_name }}'; + + const body = `## Ephemeral Environment Ready + + Your ephemeral environment has been deployed! + + **URL**: https://${dnsName} + **Cluster**: \`${clusterName}\` + **Image**: \`${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:pr-${{ github.event.pull_request.number }}\` + + The environment will be automatically destroyed when this PR is closed. + `; + + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: body + }); + + # ==================== CLEANUP ==================== + - name: Get kubeconfig for destruction + if: github.event.action == 'closed' || (failure() && steps.check-cluster.outputs.exists == 'false') + run: | + CLUSTER_NAME="${{ steps.cluster-info.outputs.cluster_name }}" + kubectl get secret ${CLUSTER_NAME}-kubeconfig \ + -n $CLUSTER_NAME \ + -o jsonpath='{.data.value}' --context tools --kubeconfig /home/runner/.kube/config | base64 -d > /tmp/kubeconfig || true + + # Rename context to match workspace name for OpenTofu + if [ -f /tmp/kubeconfig ]; then + ORIGINAL_CONTEXT=$(kubectl --kubeconfig /tmp/kubeconfig config current-context 2>/dev/null || echo "") + if [ -n "$ORIGINAL_CONTEXT" ]; then + kubectl --kubeconfig /tmp/kubeconfig config rename-context "$ORIGINAL_CONTEXT" "$CLUSTER_NAME" 2>/dev/null || true + kubectl --kubeconfig /tmp/kubeconfig config use-context "$CLUSTER_NAME" 2>/dev/null || true + fi + fi + + - name: Destroy ephemeral infrastructure + if: github.event.action == 'closed' || (failure() && steps.check-cluster.outputs.exists == 'false') + env: + KUBECONFIG: /tmp/kubeconfig + run: | + cd infra + CLUSTER_NAME="${{ steps.cluster-info.outputs.cluster_name }}" + + make ephemeral-init + make ephemeral-destroy WORKSPACE=${{ steps.cluster-info.outputs.cluster_name }} || true + + kubectl delete cluster "$CLUSTER_NAME" -n "$CLUSTER_NAME" --context tools --kubeconfig /home/runner/.kube/config || true + + ./clusters/scripts/ip_pool_manager.sh release "$CLUSTER_NAME" || true + + cypress-tests: + needs: manage-environment + if: github.event.action != 'closed' && needs.manage-environment.outputs.deployment_status == 'success' + runs-on: self-hosted + container: + image: cypress/included:13.6.4 + steps: + - name: Checkout demo-apps repository + uses: actions/checkout@v4 + with: + repository: fullstack-pw/demo-apps + path: . + + - name: Run Cypress tests + env: + APP_URL: https://${{ needs.manage-environment.outputs.dns_name }} + APP_NAME: cks-frontend + TEST_ENV: ephemeral + CYPRESS_CACHE_FOLDER: /tmp/.cache/Cypress + run: | + echo "Running Cypress tests for ${APP_NAME} at ${APP_URL}" + + # Install dependencies + npm ci + + # Run Cypress tests + npx cypress run \ + --spec "cypress/e2e/${APP_NAME}.cy.js" \ + --env CKS_FRONTEND_URL=${APP_URL},TEST_ENV=${TEST_ENV} \ + --config baseUrl=${APP_URL} diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml index 31ea603..16d4bbf 100644 --- a/.github/workflows/pipeline.yml +++ b/.github/workflows/pipeline.yml @@ -1,139 +1,139 @@ -name: App CI/CD Pipeline +# name: App CI/CD Pipeline -on: - pull_request: - branches: - - main - types: - - opened - - synchronize - - reopened - paths: - - "apps/**" - push: - branches: - - main +# on: +# pull_request: +# branches: +# - main +# types: +# - opened +# - synchronize +# - reopened +# paths: +# - "apps/**" +# push: +# branches: +# - main -permissions: - contents: write +# permissions: +# contents: write -jobs: - docker-build-and-push: - name: Build and Push - uses: fullstack-pw/pipelines/.github/workflows/build-and-push.yml@main - with: - app-context: "." - app-name: "cks-frontend" - app-dockerfile: "Dockerfile" +# jobs: +# docker-build-and-push: +# name: Build and Push +# uses: fullstack-pw/pipelines/.github/workflows/build-and-push.yml@main +# with: +# app-context: "." +# app-name: "cks-frontend" +# app-dockerfile: "Dockerfile" - update-dev-kustomization: - needs: [docker-build-and-push] - if: github.event_name == 'push' && github.ref == 'refs/heads/main' - runs-on: self-hosted - name: Deploy cks-frontend to dev - steps: - - name: Checkout code - uses: actions/checkout@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - fetch-depth: 0 +# update-dev-kustomization: +# needs: [docker-build-and-push] +# if: github.event_name == 'push' && github.ref == 'refs/heads/main' +# runs-on: self-hosted +# name: Deploy cks-frontend to dev +# steps: +# - name: Checkout code +# uses: actions/checkout@v4 +# with: +# token: ${{ secrets.GITHUB_TOKEN }} +# fetch-depth: 0 - - name: Update dev kustomization with new image tag - run: | - # Use full SHA to match the Docker tag from build-and-push.yml - VERSION="${{ github.sha }}" - KUSTOMIZATION_FILE="kustomize/overlays/dev/kustomization.yaml" +# - name: Update dev kustomization with new image tag +# run: | +# # Use full SHA to match the Docker tag from build-and-push.yml +# VERSION="${{ github.sha }}" +# KUSTOMIZATION_FILE="kustomize/overlays/dev/kustomization.yaml" - if [ ! -f "$KUSTOMIZATION_FILE" ]; then - echo "Warning: $KUSTOMIZATION_FILE not found, skipping" - exit 0 - fi +# if [ ! -f "$KUSTOMIZATION_FILE" ]; then +# echo "Warning: $KUSTOMIZATION_FILE not found, skipping" +# exit 0 +# fi - echo "Updating cks-frontend dev to version: $VERSION" - sed -i "s/newTag: .*/newTag: $VERSION/" "$KUSTOMIZATION_FILE" +# echo "Updating cks-frontend dev to version: $VERSION" +# sed -i "s/newTag: .*/newTag: $VERSION/" "$KUSTOMIZATION_FILE" - git config user.name "GitHub Actions Bot" - git config user.email "actions@github.com" - git add "$KUSTOMIZATION_FILE" - git commit -m "chore(cks-frontend): deploy $VERSION to dev [skip ci]" || echo "No changes to commit" - git push || echo "Nothing to push" +# git config user.name "GitHub Actions Bot" +# git config user.email "actions@github.com" +# git add "$KUSTOMIZATION_FILE" +# git commit -m "chore(cks-frontend): deploy $VERSION to dev [skip ci]" || echo "No changes to commit" +# git push || echo "Nothing to push" - # dev-deploy: - # needs: [docker-build-and-push] - # name: DEV deploy - # uses: fullstack-pw/pipelines/.github/workflows/deploy-kustomize.yml@main - # with: - # kustomize-dir: "./kustomize/overlays/dev" - # context: "dev" - # app-name: "cks-frontend" +# # dev-deploy: +# # needs: [docker-build-and-push] +# # name: DEV deploy +# # uses: fullstack-pw/pipelines/.github/workflows/deploy-kustomize.yml@main +# # with: +# # kustomize-dir: "./kustomize/overlays/dev" +# # context: "dev" +# # app-name: "cks-frontend" - # dev-cypress-tests: - # needs: dev-deploy - # name: DEV cypress - # uses: fullstack-pw/pipelines/.github/workflows/cypress.yml@main - # with: - # start: npm run cypress:dev - # env-vars: | - # { - # "ENQUEUER_URL": "https://dev.enqueuer.fullstack.pw", - # "ENVIRONMENT": "dev", - # "TEST_RETRIES": "2" - # } +# # dev-cypress-tests: +# # needs: dev-deploy +# # name: DEV cypress +# # uses: fullstack-pw/pipelines/.github/workflows/cypress.yml@main +# # with: +# # start: npm run cypress:dev +# # env-vars: | +# # { +# # "ENQUEUER_URL": "https://dev.enqueuer.fullstack.pw", +# # "ENVIRONMENT": "dev", +# # "TEST_RETRIES": "2" +# # } - # stg-deploy: - # # needs: [dev-cypress-tests] - # name: STG deploy - # uses: fullstack-pw/pipelines/.github/workflows/deploy-kustomize.yml@main - # with: - # kustomize-dir: "./${{ matrix.app.app_path }}/kustomize/overlays/stg" - # context: "stg" - # app-name: "cks-frontend" +# # stg-deploy: +# # # needs: [dev-cypress-tests] +# # name: STG deploy +# # uses: fullstack-pw/pipelines/.github/workflows/deploy-kustomize.yml@main +# # with: +# # kustomize-dir: "./${{ matrix.app.app_path }}/kustomize/overlays/stg" +# # context: "stg" +# # app-name: "cks-frontend" - # stg-cypress-tests: - # needs: stg-deploy - # name: STG cypress - # uses: fullstack-pw/pipelines/.github/workflows/cypress.yml@main - # with: - # start: npm run cypress:stg - # env-vars: | - # { - # "ENQUEUER_URL": "https://stg.enqueuer.fullstack.pw", - # "WRITER_URL": "https://stg.writer.fullstack.pw", - # "MEMORIZER_URL": "https://stg.memorizer.fullstack.pw", - # "ENVIRONMENT": "stg", - # "TEST_RETRIES": "2" - # } +# # stg-cypress-tests: +# # needs: stg-deploy +# # name: STG cypress +# # uses: fullstack-pw/pipelines/.github/workflows/cypress.yml@main +# # with: +# # start: npm run cypress:stg +# # env-vars: | +# # { +# # "ENQUEUER_URL": "https://stg.enqueuer.fullstack.pw", +# # "WRITER_URL": "https://stg.writer.fullstack.pw", +# # "MEMORIZER_URL": "https://stg.memorizer.fullstack.pw", +# # "ENVIRONMENT": "stg", +# # "TEST_RETRIES": "2" +# # } - # prod-deploy: - # # needs: [stg-cypress-tests] - # if: github.event_name == 'push' && github.ref == 'refs/heads/main' - # name: PROD deploy - # uses: fullstack-pw/pipelines/.github/workflows/deploy-kustomize.yml@main - # with: - # kustomize-dir: "./${{ matrix.app.app_path }}/kustomize/overlays/prod" - # context: "prod" - # app-name: "cks-frontend" +# # prod-deploy: +# # # needs: [stg-cypress-tests] +# # if: github.event_name == 'push' && github.ref == 'refs/heads/main' +# # name: PROD deploy +# # uses: fullstack-pw/pipelines/.github/workflows/deploy-kustomize.yml@main +# # with: +# # kustomize-dir: "./${{ matrix.app.app_path }}/kustomize/overlays/prod" +# # context: "prod" +# # app-name: "cks-frontend" - versioning: - permissions: - contents: write - runs-on: self-hosted - if: github.event_name == 'push' && github.ref == 'refs/heads/main' - name: Versioning - steps: - - name: Get Next Version - id: semver - uses: ietf-tools/semver-action@v1 - with: - token: ${{ github.token }} - branch: main +# versioning: +# permissions: +# contents: write +# runs-on: self-hosted +# if: github.event_name == 'push' && github.ref == 'refs/heads/main' +# name: Versioning +# steps: +# - name: Get Next Version +# id: semver +# uses: ietf-tools/semver-action@v1 +# with: +# token: ${{ github.token }} +# branch: main - - name: Create Release - uses: ncipollo/release-action@v1.12.0 - with: - allowUpdates: true - draft: false - makeLatest: true - tag: ${{ steps.semver.outputs.next }} - body: Changelog Contents - token: ${{ github.token }} +# - name: Create Release +# uses: ncipollo/release-action@v1.12.0 +# with: +# allowUpdates: true +# draft: false +# makeLatest: true +# tag: ${{ steps.semver.outputs.next }} +# body: Changelog Contents +# token: ${{ github.token }} diff --git a/Makefile b/Makefile index 49bb3bc..151e286 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,4 @@ # CKS Frontend Makefile -# Following demo-apps pattern # Variables APP_NAME = cks-frontend diff --git a/kustomize/ephemeral-base/configmap.yaml b/kustomize/ephemeral-base/configmap.yaml new file mode 100644 index 0000000..dd0e595 --- /dev/null +++ b/kustomize/ephemeral-base/configmap.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: cks-frontend-config +data: + ENVIRONMENT: env + LOG_LEVEL: loglevel + LOG_FORMAT: json + API_BASE_URL: backend diff --git a/kustomize/ephemeral-base/deployment.yaml b/kustomize/ephemeral-base/deployment.yaml new file mode 100644 index 0000000..09deceb --- /dev/null +++ b/kustomize/ephemeral-base/deployment.yaml @@ -0,0 +1,41 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cks-frontend +spec: + replicas: 1 + selector: + matchLabels: + app: cks-frontend + template: + metadata: + labels: + app: cks-frontend + spec: + containers: + - name: cks-frontend + image: registry.fullstack.pw/library/cks-frontend:latest + envFrom: + - configMapRef: + name: cks-frontend-config + ports: + - containerPort: 3000 + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 200m + memory: 256Mi + readinessProbe: + httpGet: + path: / + port: 3000 + initialDelaySeconds: 5 + periodSeconds: 10 + livenessProbe: + httpGet: + path: / + port: 3000 + initialDelaySeconds: 15 + periodSeconds: 20 diff --git a/kustomize/ephemeral-base/ingress.yaml b/kustomize/ephemeral-base/ingress.yaml new file mode 100644 index 0000000..4f65f00 --- /dev/null +++ b/kustomize/ephemeral-base/ingress.yaml @@ -0,0 +1,26 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: cks-frontend + annotations: + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/proxy-body-size: "0" + external-dns.alpha.kubernetes.io/hostname: "endpoint" + cert-manager.io/cluster-issuer: "letsencrypt-prod" +spec: + ingressClassName: "traefik" + tls: + - hosts: + - "endpoint" + secretName: cks-frontend-tls + rules: + - host: "endpoint" + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: cks-frontend + port: + number: 3000 diff --git a/kustomize/ephemeral-base/kustomization.yaml b/kustomize/ephemeral-base/kustomization.yaml new file mode 100644 index 0000000..ed78676 --- /dev/null +++ b/kustomize/ephemeral-base/kustomization.yaml @@ -0,0 +1,10 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: + - service.yaml + - configmap.yaml + - deployment.yaml + - ingress.yaml + +namespace: default diff --git a/kustomize/ephemeral-base/service.yaml b/kustomize/ephemeral-base/service.yaml new file mode 100644 index 0000000..033e5d9 --- /dev/null +++ b/kustomize/ephemeral-base/service.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: cks-frontend +spec: + selector: + app: cks-frontend + ports: + - port: 3000 + targetPort: 3000 + type: ClusterIP diff --git a/kustomize/overlays/ephemeral/configmap b/kustomize/overlays/ephemeral/configmap new file mode 100644 index 0000000..a5af656 --- /dev/null +++ b/kustomize/overlays/ephemeral/configmap @@ -0,0 +1,3 @@ +ENVIRONMENT=ephemeral +LOG_LEVEL=DEBUG +API_BASE_URL=https://dev.api.cks.fullstack.pw/api/v1 diff --git a/kustomize/overlays/ephemeral/kustomization.yaml b/kustomize/overlays/ephemeral/kustomization.yaml new file mode 100644 index 0000000..334331e --- /dev/null +++ b/kustomize/overlays/ephemeral/kustomization.yaml @@ -0,0 +1,32 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: default + +resources: + - ../../ephemeral-base + +images: + - name: registry.fullstack.pw/library/cks-frontend + newTag: pr-will-be-replaced + +patches: + - patch: |- + - op: replace + path: /metadata/annotations/external-dns.alpha.kubernetes.io~1hostname + value: "dev.cks.fullstack.pw" + - op: replace + path: /spec/tls/0/hosts/0 + value: "dev.cks.fullstack.pw" + - op: replace + path: /spec/rules/0/host + value: "dev.cks.fullstack.pw" + target: + kind: Ingress + name: cks-frontend + +configMapGenerator: + - name: cks-frontend-config + behavior: merge + envs: + - configmap