A GitOps repository for managing shared infrastructure components across multiple Konflux common clusters using ArgoCD and Kustomize.
This repository provides reusable infrastructure components and ArgoCD application definitions for deploying common services across different cluster types (internal/external) and environments (staging/production). It follows a GitOps approach where infrastructure changes are managed through Git and automatically deployed by ArgoCD.
infra-common-deployments/
├── argo-cd-apps/ # ArgoCD Application definitions
│ ├── base/
│ │ ├── all-clusters/ # Components deployed to ALL clusters
│ │ ├── external/ # Components only for external clusters
│ │ └── internal/ # Components only for internal clusters
│ └── overlays/ # Environment-specific configurations
│ ├── external-production/ # External production cluster config
│ ├── external-staging/ # External staging cluster config
│ ├── internal-production/ # Internal production cluster config
│ └── internal-staging/ # Internal staging cluster config
├── components/ # Reusable Kustomize components
│ ├── <component-name>/ # <component-name> component
│ │ └── k-components/ # Reusable <component-name> components (if any)
| ...
└── README.md
Environment | Purpose | Cluster Short Name |
---|---|---|
internal-staging | Internal Red Hat staging resources | kflux-c-stg-i01 |
internal-production | Internal Red Hat production resources | kflux-c-prd-i01 |
external-staging | External/public staging resources | kflux-c-stg-e01 |
external-production | External/public production resources | kflux-c-prd-e01 |
graph LR
A{{infra-common-clusters}}
A --> B1
A --> C1
A --> D1
A --> E1
subgraph StagingInternal[kflux-c-stg-i01]
B1>ArgoCD]
B2[internal-services]
B1 --> B2
end
subgraph StagingExternal[kflux-c-stg-e01]
C1>ArgoCD]
C2[smee]
C1 --> C2
end
subgraph ProductionInternal[kflux-c-prd-i01]
D1>ArgoCD]
D2[internal-services]
D1 --> D2
end
subgraph ProductionExternal[kflux-c-prd-e01]
E1>ArgoCD]
E2[smee]
E1 --> E2
end
This repository uses the App-of-Apps pattern where:
- A root ArgoCD Application (
all-application-sets
) manages ApplicationSets - ApplicationSets automatically discover and deploy components
- Components are deployed using Kustomize overlays per environment
- Purpose: TODO
- Location:
components/cluster-secret-store/
- Deployment: Applied only to all clusters via
all-clusters
base - Resources: ClusterSecretStore
- Purpose: Manages external secrets from various secret stores
- Location:
components/external-secrets-operator/
- Deployment: Applied to all clusters via
all-clusters
base - Resources: Subscription, operator configuration, and namespace setup
- Purpose: Group synchronization and RBAC management
- Location:
components/IAM/
- Deployment: Applied to all clusters via
all-clusters
base - Resources: Group sync operator, Konflux Rover groups, role bindings, and test platform CI admin groups
- Purpose: Webhook forwarding service for external webhooks
- Location:
components/smee/
- Deployment: Applied only to external clusters (staging/production)
- Resources: Deployment, service, and route for webhook forwarding
- Purpose: RBAC, service accounts, and internal service configurations
- Location:
components/internal-services/
- Deployment: Applied only to internal clusters (staging/production)
- Resources: Cluster roles, role bindings, service accounts, secrets, and CRD references
- Purpose: TODO
- Location:
components/openshift-pipelines/
- Deployment: Applied only to internal clusters (staging/production)
- Resources: ConfigMap, Namespace, and Subscription for OpenShift Pipelines Operator
Component | All Clusters | External Only | Internal Only |
---|---|---|---|
External Secrets Operator | âś… | - | - |
IAM (Group Sync) | âś… | - | - |
Smee | - | âś… | - |
Internal Services | - | - | âś… |
Cluster Secret Store | âś… | - | - |
Openshift Pipelines | - | - | âś… |
Each overlay includes:
- Base all-clusters: IAM + External Secrets Operator
- Environment-specific base: Additional components for that cluster type
- Environment patches: Configuration overrides for staging/production
This repository uses Kustomize Components to eliminate duplication between environments. These components are located in k-components/
directories within each component folder.
- DRY Principle: Eliminates code duplication between environments
- Maintainability: Changes only need to be made in one place
- Consistency: Ensures identical behavior across environments
- Reusability: Components can be easily used in new environments
Located in components/iam/k-components/
:
- external-ldap-url: Configures LDAP URL for external clusters
- internal-ldap-url: Configures LDAP URL for internal clusters
- konflux-ldap-sa: Manages Konflux LDAP service account configuration
- mtls-ca-validators: Manages mTLS CA validators configuration
Located in components/cluster-secret-store/k-components/
:
- approle-id: Configures AppRole ID for Vault authentication
-
Create base component directory:
mkdir -p components/my-component/base cd components/my-component/base
-
Create Kustomize base:
# kustomization.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - deployment.yaml - service.yaml namespace: my-component
Note: Be sure to name Kubernetes resource files after their Kubernetes kind
-
Add environment overlay(s):
mkdir components/my-component/internal-staging mkdir components/my-component/internal-production
-
Create overlay kustomization(s):
# components/my-component/internal-staging/kustomization.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: my-component-staging resources: - ../base patchesStrategicMerge: - staging-patches.yaml
-
Create a base ApplicationSet overlay:
Note: If your component is only on either internal or external clusters, put the ApplicationSet in the proper folder.
# argo-cd-apps/base/internal/base/my-component/appset.yaml apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: my-component spec: generators: - clusters: values: sourceRoot: components/my-component environment: base clusterName: "" template: metadata: name: my-component-{{values.clusterName}} spec: project: default source: path: '{{values.sourceRoot}}/{{values.environment}}' repoURL: https://github.com/redhat-appstudio/infra-common-deployments.git targetRevision: main destination: namespace: my-component-namespace server: '{{server}}' syncPolicy: automated: prune: true selfHeal: true syncOptions: - CreateNamespace=true retry: limit: -1 backoff: duration: 10s factor: 2 maxDuration: 3m
# argo-cd-apps/base/internal/base/my-component/kustomization.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - appset.yaml
-
Add component to base overlay:
Note: If your component is only on either internal or external clusters, add the component to the environment's base overlay
# argo-cd-apps/base/internal/base/kustomization.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - internal-services - my-component
-
Update other environment overlays if need be:
# argo-cd-apps/overlays/internal-staging/kustomization.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ../base patches: - path: environment-patch.yaml target: group: argoproj.io version: v1alpha1 kind: Application - path: special-patch.yaml target: group: argoproj.io version: v1alpha1 kind: Application name: my-component
When you have identical patches or configurations across multiple environments, consider creating a k-component:
-
Create k-components directory:
mkdir -p components/my-component/k-components/my-config
-
Create component kustomization:
# components/my-component/k-components/my-config/kustomization.yaml apiVersion: kustomize.config.k8s.io/v1alpha1 kind: Component patches: - path: my-config-patch.yaml target: name: my-resource kind: MyResource
-
Create the patch file:
# components/my-component/k-components/my-config/my-config-patch.yaml apiVersion: my-api/v1 kind: MyResource metadata: name: my-resource spec: # Your configuration here
-
Reference in environment kustomizations:
# components/my-component/external-production/kustomization.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - ../base components: - ../k-components/my-config
-
Remove duplicate patch files from individual environment directories
kustomize
CLI tool installed- Access to the repository
- Understanding of the target environment
# Test external production overlay
kustomize build argo-cd-apps/overlays/external-production/
# Test external staging overlay
kustomize build argo-cd-apps/overlays/external-staging/
# Test internal production overlay
kustomize build argo-cd-apps/overlays/internal-production/
# Test internal staging overlay
kustomize build argo-cd-apps/overlays/internal-staging/
# Check what components are included in each overlay
kustomize build argo-cd-apps/overlays/external-production/ | grep "kind:" | sort | uniq
# Expected output should include:
# - ApplicationSet (for IAM, External Secrets Operator, Smee)
# - Any other resources from the components
# Check that environment patches are applied correctly
kustomize build argo-cd-apps/overlays/external-production/ | grep -A 5 -B 5 "environment:"
# Should show "external-production" for external-production overlay
# Build just the component
kustomize build components/external-secrets-operator/base/
# Build with environment overlay
kustomize build components/external-secrets-operator/external-production/
# Build just the component
kustomize build components/IAM/base/
# Build with environment overlay
kustomize build components/IAM/external-production/
# Test individual k-component
kustomize build components/iam/k-components/konflux-ldap-sa/
# Test component with k-components
kustomize build components/iam/external-production/
When testing, verify that:
- All overlays build successfully without errors
- Environment patches are applied correctly
- Component resources are included as expected
- No duplicate resources are generated
- Namespace assignments are correct
- Resource references are valid
- Problem:
replace operation does not apply: doc is missing path
- Solution: Check that ApplicationSet structures match the expected paths for environment patches
- Problem: Expected components not appearing in build output
- Solution: Verify kustomization.yaml files include all required resources
- Problem: Environment not being set correctly
- Solution: Ensure ApplicationSet generators have the correct structure for patches
-
Problem: Component not being applied
-
Solution: Verify the component is referenced in the kustomization.yaml and the target specification matches the resource
-
Problem: Duplicate patches after creating k-component
-
Solution: Remove the original patch files from environment directories after creating the k-component
# Show kustomize build plan
kustomize build --dry-run argo-cd-apps/overlays/external-production/
# Validate YAML syntax
kustomize build argo-cd-apps/overlays/external-production/ | kubectl apply --dry-run=client -f -
# Check specific component
kustomize build components/external-secrets-operator/base/ --dry-run
- Make changes in component directory
- Test locally with kustomize build
- Verify environment overlays still work
- Test in staging before production
- Always test locally with
kustomize build
before committing - Use consistent naming conventions across components
- Keep environment-specific configs in overlays, not bases
- Document component dependencies and requirements
- Test all overlays when making changes to base components
- Fork the repository
- Create a new branch (
git checkout -b feature/my-component
) - Test changes in staging environment
- Submit a merge request with:
- Component documentation
- Environment-specific configurations
- Test validation results
- Component follows established patterns
- Environment overlays are complete
- Documentation is updated
- Security considerations addressed
- Monitoring configured
- Tested in staging environment
For issues or questions:
- Check the troubleshooting section above
- Review the component-specific documentation
- Test with kustomize build locally
- Check ArgoCD logs for deployment issues