Skip to main content

Repository Manifest Structure

Purpose: For app developers and platform engineers, documents every manifest, field convention, and directory role in the repository.

Overview

The repository uses Kustomize composition to assemble shared Gateway API resources and per-application manifests. FluxCD reconciles the root kustomization.yaml against the target cluster.

Directory layout

.
├── kustomization.yaml # Root composition
├── gateway-resources/ # Shared Gateway API definitions
│ ├── gateway.yaml
│ └── kustomization.yaml
├── app1/ # Raw-manifest application
│ ├── namespace.yaml
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── httproute.yaml
│ ├── sample-selfsigned-issuer.yaml
│ ├── sample-selfsigned-ca.yaml
│ ├── sample-ca-issuer.yaml
│ └── kustomization.yaml
├── app2/ # Helm-based application
│ ├── namespace.yaml
│ ├── source.yaml
│ ├── helmrelease.yaml
│ ├── httproute.yaml
│ ├── helm-values/
│ │ └── hardened-values-0.35.0.yaml
│ └── kustomization.yaml
├── .pre-commit-config.yaml
└── .yamllint

Root kustomization.yaml

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- "gateway-resources/"
- "app1/"
- "app2/"

Each entry is a directory containing its own kustomization.yaml. Flux and kustomize build resolve them recursively.

To add a new application, append its directory to the resources list.

gateway-resources/

Shared Gateway API resources consumed by all applications.

gateway.yaml

FieldValueNotes
apiVersiongateway.networking.k8s.io/v1beta1Gateway API version
kindGateway
metadata.namecustomer-managed-gatewayReferenced by HTTPRoutes via parentRefs
metadata.namespaceapp1Gateway lives in a single namespace; routes attach cross-namespace
metadata.annotations.cert-manager.io/cluster-issuersample-ca-issuerTriggers cert-manager certificate generation
spec.gatewayClassNameegMust match the installed gateway controller (Envoy Gateway)

Each listener defines:

Listener fieldDescription
nameUnique identifier; HTTPRoutes reference this via sectionName
portListener port (443 for HTTPS)
protocolHTTPS for TLS termination
hostnameFQDN this listener serves
tls.modeTerminate — Gateway handles TLS; backends receive plain HTTP
tls.certificateRefsSecret containing the TLS certificate (created by cert-manager)
allowedRoutes.namespaces.fromAll permits cross-namespace HTTPRoutes; Same restricts to Gateway namespace

app1/ — Raw manifest application

namespace.yaml

Creates the app1 namespace. Every application should define its own namespace for resource isolation.

deployment.yaml

FieldValue
metadata.nameweb-app
metadata.namespaceapp1
spec.replicas2
spec.template.spec.containers[0].imagenginx:latest
spec.template.spec.containers[0].resources.requestscpu: 100m, memory: 128Mi
spec.template.spec.containers[0].resources.limitscpu: 250m, memory: 256Mi

Resource requests and limits are required. Pods without limits may be evicted under memory pressure.

service.yaml

FieldValue
metadata.nameweb-app
spec.typeClusterIP
spec.ports[0]port: 80, targetPort: 80

The Service name must match the backendRefs.name in the HTTPRoute.

httproute.yaml

FieldDescription
spec.hostnamesMust match the Gateway listener hostname
spec.parentRefs[0].sectionNameMust match the Gateway listener name
spec.parentRefs[0].namespaceNamespace where the Gateway lives
spec.rules[0].backendRefsPoints to the Service by name and port
spec.rules[0].matches[0].pathPathPrefix: / catches all traffic

cert-manager resources

Three resources form the certificate issuer chain:

  1. sample-selfsigned-issuer.yamlIssuer (self-signed, in cert-manager namespace)
  2. sample-selfsigned-ca.yamlCertificate (CA cert, isCA: true, signed by the self-signed issuer)
  3. sample-ca-issuer.yamlClusterIssuer (uses the CA cert to sign application certificates)

For production, replace this chain with a real CA issuer (ACME, Vault PKI, or internal CA).

app2/ — Helm-based application

namespace.yaml

Creates the headlamp namespace.

source.yaml

FieldValue
kindHelmRepository
metadata.namespaceheadlamp
spec.urlhttps://kubernetes-sigs.github.io/headlamp/
spec.interval1h — how often Flux checks for new chart versions

helmrelease.yaml

FieldValueNotes
spec.chart.spec.chartheadlampChart name in the HelmRepository
spec.chart.spec.version0.35.0Pinned version; change to upgrade
spec.interval5mReconciliation interval
spec.timeout10mMax time for install/upgrade
spec.driftDetection.modeenabledReverts manual cluster changes
spec.install.remediation.retries3Retries on first install
spec.valuesFromSecret refsLoads values from Kubernetes Secrets

helm-values/

Contains hardened-values-<version>.yaml files. The kustomization.yaml uses secretGenerator to create a Secret from these files with disableNameSuffixHash: true so the HelmRelease reference stays stable.

httproute.yaml

Same structure as app1/httproute.yaml. References the headlamp-https listener on the shared Gateway.

Platform team manifests

These manifests are not in this repository. The platform team creates them in the cluster configuration repository to connect Flux to the application repo.

GitRepository

apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: customer-app
namespace: flux-system
spec:
interval: 1m
url: https://github.com/<org>/openCenter-customer-app-example
ref:
branch: main

interval: 1m — Flux polls the repository every minute for new commits.

Kustomization

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: customer-app
namespace: flux-system
spec:
interval: 10m
prune: true
wait: true
path: ./
sourceRef:
kind: GitRepository
name: customer-app
FieldDescription
prune: trueDeletes cluster resources when removed from Git
wait: trueWaits for resources to become ready before marking reconciliation complete
path: ./Renders from the repository root

Linting configuration

.yamllint

RuleSetting
indentation.spaces2
indentation.indent-sequencesconsistent
line-length.max120
truthy.allowed-valuestrue, false, on, off, yes, no

.pre-commit-config.yaml

Runs yamllint --strict on all files before commit using the mirrors-yamllint hook (v1.35.1).