Adding a Platform Component¶
A platform component is a directory under payload/platform/ with exactly one
application.yaml; the platform ApplicationSet turns it into an ArgoCD
Application on the next poll. Workloads go in the
other repository. Why the platform is shaped this way is in
GitOps Strategy.
Steps¶
-
Create the directory with a complete
application.yamlcopied from a sibling: the generator copies its labels, annotations, finalizers andspecverbatim, so a fragment is not an Application. It carriesproject: infra, like every component except the two that configure ArgoCD itself. Keep the sync policy as it is — every component carries the same one,retryincluded, and a chart that lands before its CRDs stays failed without it. -
Pin the version once, as
targetRevisionin that file. TheMakefilereads the bootstrap versions out of these manifests and Renovate bumps them there — see Version pins. -
Put each resource with what it needs, not with what it configures. Nothing orders the Applications, so a
ClusterSecretStoresits with OpenBao and the issuers are their own component — see Bootstrap convergence. A resource whose CRD comes from another component getsargocd.argoproj.io/sync-options: SkipDryRunOnMissingResource=true. A component with anExternalSecretneeds its namespace in both lists ofpayload/platform/openbao/cluster-secret-store.yaml, or the ExternalSecret readsdenied by spec.condition. A chart from a new repository needs that host in the repo-server's policy inpayload/platform/security/network-policies/argocd.yaml, or the Application readsComparisonError. -
Label the namespace in
payload/platform/security/pod-security.yamlwith the Pod Security Admission level it demonstrably needs, one sentence of why next to anyprivileged, and add aprivilegedone to the list innamespace-privileged-allowed— see Security Policies. Then deny it to workloads: add"!<namespace>"to theappsproject's destinations inpayload/platform/argocd-projects/projects.yaml, which otherwise lets every workload Application write into it. Aprivilegednamespace is the one that matters: the admission policy guards new Namespaces, not deployments into an existing one, so a workload commit could place a host-networked pod on every node. -
Write its network policy as
payload/platform/security/network-policies/<namespace>.yaml: thedefault-ingressanddefault-egressdeny pair plus one policy per workload that needs more, copied from the namespace most like it. New HTTP rules start ashttp: [{}]until the rollout has recorded a week of requests. -
Expose a UI with an
HTTPRouteoninfra-gatewaynext to the component, and put it behind Authentik — see Gateway API and Authentik. A route that crosses namespaces needs aReferenceGrantin the target namespace. -
Check Renovate sees the pin. Chart versions are covered; an image tag inside
valuesObjectneeds a# renovate:comment — see Maintenance. -
Write the page under
docs/platform/with the shared skeleton — intro, At a glance, Configuration, Usage, Health check, Pitfalls, Recovery only with a real runbook — add it to the nav inzensical.tomland to the Components table. The strict docs build fails on a page the nav does not list. -
Open the PR and run the checks in Contributing. After the merge the Application appears within one polling interval; a Degraded one is usually waiting on a CRD, a Secret or OpenBao — see Troubleshooting.