Installation¶
Prerequisites¶
- kubectl v1.28+
- Access to a Kubernetes v1.28+ cluster
- AWS credentials with CloudFront permissions
- Helm 3.x (for Helm-based installation)
For development, you additionally need:
- Go 1.25+
- Docker 17.03+
Required AWS IAM Permissions¶
Core permissions (required)¶
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudfront:CreateDistributionTenant",
"cloudfront:GetDistributionTenant",
"cloudfront:UpdateDistributionTenant",
"cloudfront:DeleteDistributionTenant",
"cloudfront:GetDistribution",
"cloudfront:GetManagedCertificateDetails",
"cloudfront:GetConnectionGroup",
"cloudfront:ListConnectionGroups"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"acm:RequestCertificate",
"acm:DescribeCertificate"
],
"Resource": "*"
}
]
}
| Permission | Used For |
|---|---|
CreateDistributionTenant |
Creating new tenants |
GetDistributionTenant |
Fetching current state for drift detection and status updates |
UpdateDistributionTenant |
Pushing spec changes and disabling before deletion |
DeleteDistributionTenant |
Removing tenants from AWS |
GetDistribution |
Pre-flight validation (certificate coverage, required parameters) |
GetManagedCertificateDetails |
Tracking managed certificate lifecycle |
GetConnectionGroup |
Resolving a connection group's routing endpoint for DNS |
ListConnectionGroups |
Finding the default connection group's routing endpoint |
acm:RequestCertificate |
Requesting managed ACM certificates via managedCertificateRequest |
acm:DescribeCertificate |
Validating certificate SANs cover tenant domains |
DNS management permissions (optional)¶
Required only if you configure spec.dns on your tenants:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"route53:ChangeResourceRecordSets",
"route53:GetChange"
],
"Resource": "*"
}
]
}
If you use spec.dns.assumeRoleArn for cross-account DNS, the operator also needs sts:AssumeRole on the target role.
Install with Helm (Recommended)¶
The chart is published as an OCI artifact. CRDs are bundled in the chart's crds/ directory and are automatically installed on first helm install.
Install from OCI registry¶
helm install cloudfront-tenant-operator \
oci://ghcr.io/dsp0x4/charts/cloudfront-tenant-operator \
--version <version> \
--namespace cloudfront-tenant-operator-system \
--create-namespace
Install from local source¶
If you cloned the repository, you can install directly from the chart directory:
helm install cloudfront-tenant-operator dist/chart/ \
--namespace cloudfront-tenant-operator-system \
--create-namespace
Configuration¶
Override defaults via --set or a custom values file:
helm install cloudfront-tenant-operator \
oci://ghcr.io/dsp0x4/charts/cloudfront-tenant-operator \
--version <version> \
--namespace cloudfront-tenant-operator-system \
--create-namespace \
--set aws.region=us-east-1 \
--set controller.driftPolicy=report \
--set controller.maxConcurrentReconciles=3
Or with a values file:
helm install cloudfront-tenant-operator \
oci://ghcr.io/dsp0x4/charts/cloudfront-tenant-operator \
--version <version> \
--namespace cloudfront-tenant-operator-system \
--create-namespace \
-f my-values.yaml
See dist/chart/values.yaml for all available options.
Upgrade¶
Helm does not update CRDs on upgrade (by design, to prevent accidental data loss). When upgrading to a version with CRD changes, apply the CRDs manually before running helm upgrade.
From OCI registry:
# 1. Pull the chart to extract updated CRDs
helm pull oci://ghcr.io/dsp0x4/charts/cloudfront-tenant-operator \
--version <new-version> --untar --untardir /tmp
# 2. Apply updated CRDs
kubectl apply -f /tmp/cloudfront-tenant-operator/crds/
# 3. Upgrade the operator
helm upgrade cloudfront-tenant-operator \
oci://ghcr.io/dsp0x4/charts/cloudfront-tenant-operator \
--version <new-version> \
--namespace cloudfront-tenant-operator-system
From local source:
# 1. Apply updated CRDs
kubectl apply -f dist/chart/crds/
# 2. Upgrade the operator
helm upgrade cloudfront-tenant-operator dist/chart/ \
--namespace cloudfront-tenant-operator-system
Uninstall¶
# Remove the operator (CRDs and CRs are preserved)
helm uninstall cloudfront-tenant-operator \
--namespace cloudfront-tenant-operator-system
# If you also want to remove CRDs (this deletes ALL DistributionTenant resources):
kubectl delete -f dist/chart/crds/
Install with Kustomize¶
Install CRDs¶
Deploy the operator¶
Uninstall¶
kubectl delete -k config/samples/ # Delete CRs
make undeploy # Remove operator
make uninstall # Delete CRDs
Run Locally (Development)¶
Configure AWS Credentials¶
The operator pod needs AWS credentials to call the CloudFront and Route53 APIs. On EKS, use one of the native IAM integration methods below. On non-EKS clusters, fall back to environment variables or mounted secrets.
EKS Pod Identity (recommended)¶
EKS Pod Identity is the recommended approach. It requires no service account annotations and works at the cluster level.
1. Install the Pod Identity Agent add-on (one-time per cluster):
2. Create an IAM role with a trust policy for Pod Identity:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "Service": "pods.eks.amazonaws.com" },
"Action": ["sts:AssumeRole", "sts:TagSession"]
}
]
}
Attach the required IAM permissions to this role.
3. Create the Pod Identity association:
aws eks create-pod-identity-association \
--cluster-name <cluster> \
--namespace cloudfront-tenant-operator-system \
--service-account <service-account-name> \
--role-arn arn:aws:iam::123456789012:role/my-operator-role
Replace <service-account-name> with the service account created by the Helm chart (defaults to the release name).
No Helm value changes are needed -- the Pod Identity Agent injects credentials automatically.
IAM Roles for Service Accounts (IRSA)¶
IRSA works by annotating the service account with an IAM role ARN. It requires an OIDC provider configured on the cluster.
With Helm:
helm install cloudfront-tenant-operator dist/chart/ \
--namespace cloudfront-tenant-operator-system \
--create-namespace \
--set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::123456789012:role/my-operator-role
Static credentials (non-EKS, not recommended)¶
Warning: Static credentials do not rotate automatically and increase the risk of credential leakage. Prefer Pod Identity or IRSA whenever possible. Use this method only on non-EKS clusters where no better alternative is available.
For non-EKS clusters, inject AWS credentials via environment variables using the extraEnv chart value: