diff --git a/k8s/providers/hetzner/apps/aws/flux-kustomization.yaml b/k8s/providers/hetzner/apps/aws/flux-kustomization.yaml new file mode 100644 index 000000000..ea922eddc --- /dev/null +++ b/k8s/providers/hetzner/apps/aws/flux-kustomization.yaml @@ -0,0 +1,36 @@ +# Applies the AWS desired state from the devantler-tech/aws OCI artifact into +# this namespace, AS the namespace-scoped `aws` ServiceAccount — so once +# platform#2326 activates the IAM managed-resource kinds, the MRs are created +# with only the authority a namespaced Role grants that SA (none is bound yet: +# the artifact is an empty scaffold today, and RBAC is widened strictly +# alongside ManagedResourceActivationPolicy entries, mirroring unifi). It is +# itself applied by the `apps` Flux Kustomization; it must NOT dependsOn it +# (deadlock) — it retries benignly until the provider (infrastructure layer) +# has established the namespaced aws CRDs. +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: aws + namespace: aws + labels: + app.kubernetes.io/managed-by: ksail + annotations: + ksail.devantler.tech/reconcile-exclude: "true" +spec: + interval: 1m + timeout: 5m + retryInterval: 2m + path: . + prune: true + wait: true + # No force: these are Crossplane managed resources with the default + # deletionPolicy: Delete, so a force delete/recreate on immutable-field drift + # would cascade into deleting the backing AWS object. Handle a genuine + # immutable conflict per-resource with the + # kustomize.toolkit.fluxcd.io/force: enabled annotation instead. + serviceAccountName: aws + sourceRef: + kind: OCIRepository + name: aws + targetNamespace: aws diff --git a/k8s/providers/hetzner/apps/aws/kustomization.yaml b/k8s/providers/hetzner/apps/aws/kustomization.yaml index 9b7f3deb9..b61240dff 100644 --- a/k8s/providers/hetzner/apps/aws/kustomization.yaml +++ b/k8s/providers/hetzner/apps/aws/kustomization.yaml @@ -8,3 +8,5 @@ resources: - secret-store.yaml - provider-config.yaml - external-secret.yaml + - oci-repository.yaml + - flux-kustomization.yaml diff --git a/k8s/providers/hetzner/apps/aws/oci-repository.yaml b/k8s/providers/hetzner/apps/aws/oci-repository.yaml new file mode 100644 index 000000000..1b637d26f --- /dev/null +++ b/k8s/providers/hetzner/apps/aws/oci-repository.yaml @@ -0,0 +1,31 @@ +# The aws tenant's source — the same delivery pattern as github-config +# (cosign-verified OCI artifact → namespace-scoped Kustomization), carrying the +# devantler-tech/aws repo's deploy/ artifact: the declarative AWS state +# (Crossplane managed resources; IAM kinds arrive with platform#2326). The +# artifact is published as a signed OCI image by that repo's cd.yaml on v* tags. +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: aws + namespace: aws + labels: + app.kubernetes.io/managed-by: ksail +spec: + interval: 1m + ref: + semver: ">=1.0.0" + # No secretRef: the package is public (non-secret desired-state config, no + # credentials — those live in OpenBao), so it is pulled anonymously. + url: oci://ghcr.io/devantler-tech/aws/manifests + verify: + provider: cosign + matchOIDCIdentity: + # Keyless-signed by the shared publish-manifests reusable workflow that + # aws's cd.yaml calls. Signing runs INSIDE that reusable workflow, so the + # cosign OIDC subject is the reusable workflow's path, NOT aws's own + # cd.yaml. Unlike the older tenants there is no reusable-workflows + # alternation here: the aws repo was scaffolded after the actions#425 + # repoint, so every artifact it has ever published is actions-signed. + - issuer: '^https://token\.actions\.githubusercontent\.com$' + subject: '^https://github\.com/devantler-tech/actions/\.github/workflows/publish-manifests\.yaml@.+$'