Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/actionlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
self-hosted-runner:
labels:
- arc-tf
6 changes: 3 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Setup Python
uses: actions/setup-python@v5
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.12"

- name: pre-commit tests
uses: pre-commit/action@v3.0.1
uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
8 changes: 4 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
repos:
- repo: https://github.com/compilerla/conventional-pre-commit
rev: v4.4.0
rev: 91ab4bf57e58b32adf1a122681f6ebe164d081c8 # v4.4.0
hooks:
- id: conventional-pre-commit
stages: [commit-msg]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v6.0.0
rev: 3e8a8703264a2f4a69428a0aa4dcb512790b2c8c # v6.0.0
hooks:
- id: check-case-conflict
- id: check-merge-conflict
Expand All @@ -20,12 +20,12 @@ repos:
- id: mixed-line-ending
- id: trailing-whitespace
- repo: https://github.com/gitleaks/gitleaks
rev: v8.30.1
rev: 83d9cd684c87d95d656c1458ef04895a7f1cbd8e # v8.30.1
hooks:
- id: gitleaks
entry: gitleaks dir --redact --verbose .
pass_filenames: false
- repo: https://github.com/stackrox/kube-linter
rev: v0.8.3
rev: 10ae003038c81855aca8489df5e35da150f4dc2e # v0.8.3
hooks:
- id: kube-linter
2 changes: 1 addition & 1 deletion .sops.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
creation_rules:
# Default: encrypt only common secret fields
# Encrypt credential fields only so metadata remains reviewable.
- age: age152ek83tm4fj5u70r3fecytn4kg7c5xca24erjchxexx4pfqg6das7q763l
encrypted_regex: '^(token|api-token|apiToken|clientID|clientSecret|client_id|client_secret|password|secret|github_token|CLOUDFLARE_API_TOKEN|credentials\.json|.*_SERVICE_KEY|GF_AUTH_(GITHUB|GENERIC_OAUTH)_CLIENT_SECRET|GF_SECURITY_ADMIN_PASSWORD|dex\.[a-z]+\.clientID|dex\.[a-z]+\.clientSecret|OIDC_CLIENT_(ID|SECRET))$'

Expand Down
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ The root `kustomization.yaml` is for local `kustomize build` testing only. ArgoC
## Sync Wave Flow

```
Wave 0: ArgoCD configuration, RBAC, CI service account
Wave 1: bootstrap-secrets and gitops-operators Applications
Wave 2: gitops-workloads Application
PostSync: ci-token-sync, wait-for-* jobs
Bootstrap apply: ArgoCD configuration, RBAC, CI, and independent root Applications
gitops-operators: installs operator controllers and CRDs
gitops-workloads PreSync: wait-for-crds blocks until required CRDs exist
gitops-workloads Sync: creates child Applications and direct workload CRs
```

Sync waves order resources within a single Application — they are not global across Applications. Cross-Application ordering is enforced by the App-of-Apps structure and `wait-for-*` post-sync jobs.
The `bootstrap-secrets`, `gitops-operators`, and `gitops-workloads` root
Applications reconcile independently. Sync waves are local to each Application;
the `gitops-workloads` `PreSync` hook gates its child Application and direct CR
creation until every workload-required operator CRD is available.

## External Traffic

Expand Down
23 changes: 8 additions & 15 deletions bootstrap/argocd-config.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
---
# ArgoCD instance managed by argocd-operator (community).
# - KSOPS for SOPS-encrypted secrets using AGE keys
# - GitHub OAuth authentication via Dex
# - RBAC with GitHub org/team mapping
apiVersion: argoproj.io/v1beta1
kind: ArgoCD
metadata:
Expand All @@ -11,9 +7,12 @@ metadata:
annotations:
argocd.argoproj.io/sync-wave: "0"
spec:
# Disable local admin account - use GitHub SSO instead
# Interactive access must use GitHub SSO.
disableAdmin: true
# Server configuration
# API-only account; RBAC below restricts it to Application operations.
extraConfig:
accounts.mcp: apiKey
# CPU limits are omitted to avoid throttling on the single-node cluster.
server:
host: argocd.makeitwork.cloud
resources:
Expand All @@ -22,31 +21,27 @@ spec:
memory: 128Mi
limits:
memory: 256Mi
# Controller resources (no CPU limits to prevent throttling)
controller:
resources:
requests:
cpu: 250m
memory: 1Gi
limits:
memory: 2Gi
# ApplicationSet controller resources
applicationSet:
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
memory: 1Gi
# Redis resources
redis:
resources:
requests:
cpu: 250m
memory: 128Mi
limits:
memory: 256Mi
# KSOPS configuration
kustomizeBuildOptions: "--enable-alpha-plugins --enable-exec"
repo:
resources:
Expand All @@ -67,7 +62,6 @@ spec:
secret:
secretName: sops-age-keys
initContainers:
# Use alpine to download and install KSOPS binaries
- name: install-ksops
image: docker.io/alpine:3.23
command: ["/bin/sh", "-c"]
Expand All @@ -93,7 +87,6 @@ spec:
- mountPath: /.config/sops/age/key.txt
name: sops-age-keys
subPath: key.txt
# GitHub OAuth via Dex (SSO)
sso:
provider: dex
dex:
Expand Down Expand Up @@ -132,12 +125,12 @@ spec:
secret: $dex.forgejo.clientSecret
redirectURIs:
- https://forgejo.makeitwork.cloud/user/oauth2/dex/callback
# RBAC with GitHub team mapping
rbac:
defaultPolicy: ''
policy: |
# Admin access for admins team
g, makeitworkcloud:admins, role:admin
# Read-only access for developers team
g, makeitworkcloud:developers, role:readonly
# MCP has no access to projects, repositories, clusters, or accounts.
p, mcp, applications, get, */*, allow
p, mcp, applications, sync, */*, allow
scopes: '[groups]'
9 changes: 4 additions & 5 deletions bootstrap/ci-service-account.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
---
# Service account for CI/CD pipelines (GitHub Actions)
# Token is created as a long-lived secret for headless authentication
apiVersion: v1
kind: ServiceAccount
metadata:
Expand All @@ -9,8 +7,8 @@ metadata:
annotations:
argocd.argoproj.io/sync-wave: "0"
---
# Long-lived API token for CI/CD
# Extract with: kubectl get secret ci-deployer-token -n argocd -o jsonpath='{.data.token}' | base64 -d
# External GitHub Actions cannot use projected pod tokens, so this Secret
# provides the long-lived credential synchronized to approved repositories.
apiVersion: v1
kind: Secret
metadata:
Expand All @@ -21,7 +19,8 @@ metadata:
kubernetes.io/service-account.name: ci-deployer
type: kubernetes.io/service-account-token
---
# Grant cluster-admin to CI service account
# Security boundary: this token is cluster-admin and must be distributed only
# to the approved CI repositories.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
Expand Down
1 change: 0 additions & 1 deletion bootstrap/ci-token-sync-job.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ spec:
# (NOT the auto-mounted bound token which expires in 1 hour)
SA_TOKEN=$(cat /var/run/secrets/ci-deployer/token)

# Repos that need the ci-deployer cluster API token
REPOS=(
"makeitworkcloud/images"
"makeitworkcloud/kustomize-cluster"
Expand Down
10 changes: 0 additions & 10 deletions bootstrap/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
# Wave 0: Configure ArgoCD (KSOPS + GitHub OAuth + RBAC)
# NOTE: cluster-admin ClusterRoleBinding is managed by ansible-role-crc
# (ArgoCD cannot grant itself permissions it doesn't have)
- argocd-config.yaml
# Wave 0: GitHub-team-to-cluster-admin RBAC for kubectl OIDC users
- oidc-rbac.yaml
# Wave 0: CI/CD service account with cluster-admin for GitHub Actions
- ci-service-account.yaml
# PostSync: Sync ci-deployer token to GitHub Actions secrets
- ci-token-sync-job.yaml
- wait-for-repo-server.yaml
# Wave 1: Bootstrap secrets (KSOPS-dependent)
- bootstrap-secrets-app.yaml
# Wave 1: Deploy operators (install CRDs)
- operators-app.yaml
- wait-for-crds.yaml
# Wave 2: Deploy workloads (CRs that depend on CRDs)
- workloads-app.yaml
1 change: 0 additions & 1 deletion bootstrap/secrets/ci-token-sync-secret.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# GitHub PAT for CI token sync job
apiVersion: v1
kind: Secret
metadata:
Expand Down
1 change: 0 additions & 1 deletion bootstrap/secrets/github-oauth-secret.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# GitHub OAuth credentials for ArgoCD Dex connector
# This secret must be labeled to be read by ArgoCD
apiVersion: v1
kind: Secret
Expand Down
73 changes: 0 additions & 73 deletions bootstrap/wait-for-crds.yaml

This file was deleted.

2 changes: 2 additions & 0 deletions opencode.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"aws-prod": {"enabled": false},
"grafana": {"enabled": false},
"terraform-docs": {"enabled": false},
"argocd-makeitwork": {"enabled": true},
"argocd-staging-eks": {"enabled": false},
"argocd-prod-eks": {"enabled": false}
},
Expand All @@ -30,6 +31,7 @@
"aws-prod_*": false,
"grafana_*": false,
"terraform-docs_*": false,
"argocd-makeitwork_*": true,
"argocd-staging-eks_*": false,
"argocd-prod-eks_*": false
}
Expand Down
1 change: 0 additions & 1 deletion operators/cert-manager/cloudflare-api-token-secret.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# Cloudflare API token for cert-manager DNS-01 challenges
apiVersion: v1
kind: Secret
metadata:
Expand Down
5 changes: 0 additions & 5 deletions operators/cert-manager/cluster-issuer.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
---
# ClusterIssuer for Let's Encrypt with Cloudflare DNS-01 challenge
# Used to issue certificates for *.makeitwork.cloud domains
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
Expand All @@ -9,11 +7,8 @@ metadata:
argocd.argoproj.io/sync-wave: "2"
spec:
acme:
# Production Let's Encrypt server
server: https://acme-v02.api.letsencrypt.org/directory
# Email for certificate expiry notifications
email: admin@makeitwork.cloud
# Secret to store ACME account private key
privateKeySecretRef:
name: letsencrypt-cloudflare-account-key
solvers:
Expand Down
3 changes: 0 additions & 3 deletions operators/cloudflare/cluster-tunnel.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,14 @@ spec:
domain: makeitwork.cloud
secret: cloudflare-api-credentials
CLOUDFLARE_API_TOKEN: CLOUDFLARE_API_TOKEN
# Default fallback for unmatched requests
fallbackTarget: http_status:404
# Patch the cloudflared deployment
deployPatch: |
spec:
template:
spec:
containers:
- name: cloudflared
image: docker.io/cloudflare/cloudflared:latest
# Increase probe delays to allow tunnel connection time
livenessProbe:
initialDelaySeconds: 30
periodSeconds: 30
Expand Down
4 changes: 1 addition & 3 deletions operators/cloudflare/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
# Operator from upstream GitHub release
- https://github.com/adyanth/cloudflare-operator.git/config/default?ref=v0.13.1
# ClusterTunnel CR (cloudflared deployment created by operator)
- cluster-tunnel.yaml
generators:
- ksops-cloudflare-secrets.yaml
images:
- name: adyanth/cloudflare-operator
newName: docker.io/adyanth/cloudflare-operator
patches:
# Remove container resource requests/limits from operator deployment
# Omit resource constraints on the single-node cluster.
- patch: |
- op: remove
path: /spec/template/spec/containers/0/resources
Expand Down
Loading
Loading