Developer deployment guide for Unified Chart
Introduction
This guide provides detailed instructions for deploying applications to W.W. Norton's AWS EKS (Kubernetes) clusters. It covers the complete deployment workflow, from setting up your deployment repository to monitoring your application in the cluster.
Prerequisites
Before starting the deployment process, ensure you have:
- A working application with containerized build process
- Access to W.W. Norton's GitLab organization
- Your application's GitLab CI pipeline configured and working
- Required access to the cluster-manager repository
- Basic understanding of Kubernetes, Helm, and FluxCD concepts
Application Deployment project
If you are migrating from per-app/custom Helm Chart in your deployment project, you can follow this documentation.
For new deployment projects, continue reading below.
Deployment project Structure
Your application requires a dedicated deployment repository (-deploy) with the following structure:
<application-name>-deploy/
├── CODEOWNERS # Define repository maintainers
├── README.md # Repository documentation
└── flux/ # Environment-specific values
├── dev/
│ ├── kustomization.yaml # Development Kustomization environment values
│ └── values.yaml # Development environment values
├── prod/
│ ├── kustomization.yaml # Production Kustomization environment values
│ └── values.yaml # Production environment values
├── qa/
│ ├── kustomization.yaml # QA Kustomization environment values
│ └── values.yaml # QA environment values
└── stg/
├── kustomization.yaml # Staging Kustomization environment values
└── values.yaml # Staging environment values
Key Components:
- CODEOWNERS: Defines who can approve changes to the repository. Example format:
* @app-team/flux/ @platform-team @app-team
- Flux Directory
- Contains environment-specific values
- Each subdirectory represents a deployment environment
- Values files override default chart values for each environment
Version Control Practices
- Branch Strategy
- Main branch is protected
- By default, "Allowed to push and merge" in Deploy Project Settings Branch Rules' Protect Branch only applies to "Maintainers". This needs to be updated to "Developers and Maintainers" to allow Developers to trigger pipelines in Deploy projects.
- All changes must go through Merge Requests
- Environment-specific changes should use feature branches
- Main branch is protected
- Change Management
- All changes must be reviewed by designated approvers
- Changes affecting platform configurations require platform team approval
- Documentation updates should accompany configuration changes
Helm Chart Configuration
The Helm Chart configuration now relies on the Unified Chart so you no longer need to set any Chart in this deploy repository.
If you want to test your values.yaml against Unified Chart schema, you can use Helm CLI and run the following command:
$ cd <PATH_TO_UNIFIED_CHART_DIRECTORY>
$ helm lint ./chart -f <PATH_TO_YOUR_VALUES_FILE>
Kustomization Configuration
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: <application-name>-values
files:
- values.yaml
generatorOptions:
disableNameSuffixHash: true
FluxCD Configuration
When your Deployment Repository is ready for deployment, you'll need to configure FluxCD to manage your application in the cluster. This requires the following main components:
- GitRepository (unified-chart & deploy repository)
- HelmRelease
- Kustomization
All these components should be merged in a single YAML file ("<application-name>.yaml")
GitRepository Configuration
The GitRepository resource tells Flux where to find Unified Helm Chart and your deployment repositories.
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: <application-name>-unified-chart
namespace: flux-system
spec:
interval: 1m
url: https://gitlab.com/wwnorton/ops/unified-chart
ref:
tag: <unified-chart-version>
secretRef:
name: flux-git-auth-ops
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: <application-name>-deploy
namespace: flux-system
spec:
interval: 1m
url: <application-gitlab-repository-url>
ref:
branch: <application-gitlab-branch-name>
secretRef:
name: flux-git-auth
HelmRelease Configuration
The HelmRelease resource defines how Flux should deploy your Helm chart.
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: <application-name>
namespace: <application-namespace>
spec:
interval: 1m
chart:
spec:
chart: "./chart"
reconcileStrategy: Revision
sourceRef:
kind: GitRepository
name: <application-name>-unified-chart
namespace: flux-system
valuesFrom:
- kind: ConfigMap
name: <application-name>-values
valuesKey: values.yaml
Flux Kustomization Configuration
This is a Flux Kustomization resource (kustomize.toolkit.fluxcd.io) — not the Kustomize file in your deploy repo (kustomize.config.k8s.io, covered above). It tells Flux to read ./flux/<environment> from your deploy repository, apply the local kustomization.yaml, and create the <application-name>-values ConfigMap in <application-namespace>.
That ConfigMap is what the HelmRelease consumes through valuesFrom. When you merge values in the deploy repo, Flux updates the ConfigMap on the next reconcile; the HelmRelease then picks up the new values and redeploys the chart.
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: <application-name>-values
namespace: flux-system
spec:
interval: 1m
sourceRef:
kind: GitRepository
name: <application-name>-deploy
path: ./flux/<environment>
prune: true
targetNamespace: <application-namespace>
Final merged file
This is the result file with all components merged into a single file.
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: <application-name>-unified-chart
namespace: flux-system
spec:
interval: 1m
url: https://gitlab.com/wwnorton/ops/unified-chart
ref:
tag: <unified-chart-version>
secretRef:
name: flux-git-auth-ops
---
apiVersion: source.toolkit.fluxcd.io/v1beta1
kind: GitRepository
metadata:
name: <application-name>-deploy
namespace: flux-system
spec:
interval: 1m
url: <application-gitlab-repository-url>
ref:
branch: <application-gitlab-branch-name>
secretRef:
name: flux-git-auth
---
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: <application-name>
namespace: <application-namespace>
spec:
interval: 1m
chart:
spec:
chart: "./chart"
reconcileStrategy: Revision
sourceRef:
kind: GitRepository
name: <application-name>-unified-chart
namespace: flux-system
valuesFrom:
- kind: ConfigMap
name: <application-name>-values
valuesKey: values.yaml
---
apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
kind: Kustomization
metadata:
name: <application-name>-values
namespace: flux-system
spec:
interval: 1m
sourceRef:
kind: GitRepository
name: <application-name>-deploy
path: ./flux/<environment>
prune: true
targetNamespace: <application-namespace>
Important Notes:
- File Placement. Configuration should be in:
./clusters/<cluster-name>/flux-config/<application-name>.yaml
- Repository Access
- Requires GitLab repository access
- Uses
flux-git-authsecret (do not modify) - Ensure proper permissions
- Synchronization
- Default 1-minute sync interval
- Adjustable based on needs
- Consider resource implications
- Environment Handling
- Separate values per environment
- Path structure must match
- Consider environment variables
- Namespace Management
- Use appropriate target namespace
- Ensure namespace exists
- Consider resource quotas
- Deployment Strategy
Revisionstrategy for GitOps- Automatic reconciliation
- Rollback capabilities
- Monitoring Setup
- Watch reconciliation status
- Monitor Flux logs
- Set up alerts for failures
- Security Considerations
- Use specific branches
- Implement access controls
- Secure sensitive values
Conclusion - Deploying your application
Throughout this guide, we've built a comprehensive values configuration for your application. All these configurations come together in environment-specific values files located at ./flux/<environment>/values.yaml. Here's how to bring it all together:
Values file structure
Your final values.yaml must be a valid one. You should use helm lint command along Unified Chart's schema as described here.
Adding Your Application to the Cluster
- Example Repository
- Reference Implementation: Ebook's Nerd Service
- Create Flux Configuration
- Submit a Merge Request to Cluster Manager Repository and notify a platform team member for approval.
- Add new merged file into
clusters/tf-<env>-cluster/flux-config/directory:
├── <application-name>.yaml
- Monitor Deployment
- Watch Flux logs for reconciliation (using Flux-CLI)
- Check application pods and services
- Verify ingress configuration
- Test application endpoints
Next Steps
- Ensure all required secrets exist in the target namespace
- Monitor the deployment progress
- Test your application endpoints
For additional support or questions, please reach out to the Platform Team