🎯 Exemplos recomendados
Balanced sample collections from various categories for you to explore
Exemplos Helm Chart
Exemplos completos de Helm charts com templates, valores, dependências e configurações de gerenciamento de pacotes
💻 Helm Chart de Aplicação Web Básica
🟢 simple
⭐⭐
Estrutura completa de Helm chart para aplicação web com deployment, service e ingress configuráveis
⏱️ 15 min
🏷️ helm, chart, kubernetes, templates
Prerequisites:
Kubernetes basics, Helm fundamentals, YAML syntax
# Basic Web Application Helm Chart Structure
# 1. Chart.yaml - Chart Metadata
apiVersion: v2
name: web-app
description: A Helm chart for web application deployment
type: application
version: 1.0.0
appVersion: "1.0.0"
home: https://github.com/example/web-app
sources:
- https://github.com/example/web-app
maintainers:
- name: DevOps Team
email: [email protected]
keywords:
- web
- application
- nginx
annotations:
category: WebApplication
licenses: MIT
# 2. values.yaml - Default Configuration
replicaCount: 1
image:
repository: nginx
pullPolicy: IfNotPresent
tag: "1.21-alpine"
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
podAnnotations: {}
podSecurityContext:
fsGroup: 2000
securityContext:
# capabilities:
# drop:
# - ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
service:
type: ClusterIP
port: 80
targetPort: 80
annotations: {}
ingress:
enabled: false
className: "nginx"
annotations: {}
# kubernetes.io/ingress.class: nginx
# cert-manager.io/cluster-issuer: letsencrypt-prod
hosts:
- host: web-app.local
paths:
- path: /
pathType: Prefix
tls: []
# - secretName: web-app-tls
# hosts:
# - web-app.local
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
# Application specific configuration
app:
env: production
logLevel: info
features:
- authentication
- monitoring
- caching
# Database configuration
database:
enabled: false
host: ""
port: 5432
name: webapp
user: webapp
password: ""
sslMode: require
# Redis configuration
redis:
enabled: false
host: ""
port: 6379
password: ""
database: 0
# Monitoring configuration
monitoring:
enabled: false
serviceMonitor:
enabled: false
namespace: ""
labels: {}
annotations: {}
interval: 30s
scrapeTimeout: 10s
# 3. templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "web-app.fullname" . }}
labels:
{{- include "web-app.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "web-app.selectorLabels" . | nindent 6 }}
template:
metadata:
annotations:
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
checksum/secret: {{ include (print $.Template.BasePath "/secret.yaml") . | sha256sum }}
{{- with .Values.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "web-app.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "web-app.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.targetPort }}
protocol: TCP
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /ready
port: http
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
env:
- name: APP_ENV
value: {{ .Values.app.env | quote }}
- name: LOG_LEVEL
value: {{ .Values.app.logLevel | quote }}
- name: FEATURES
value: {{ join "," .Values.app.features | quote }}
{{- if .Values.database.enabled }}
- name: DATABASE_HOST
value: {{ .Values.database.host | quote }}
- name: DATABASE_PORT
value: {{ .Values.database.port | quote }}
- name: DATABASE_NAME
value: {{ .Values.database.name | quote }}
- name: DATABASE_USER
value: {{ .Values.database.user | quote }}
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "web-app.fullname" . }}
key: database-password
- name: DATABASE_SSL_MODE
value: {{ .Values.database.sslMode | quote }}
{{- end }}
{{- if .Values.redis.enabled }}
- name: REDIS_HOST
value: {{ .Values.redis.host | quote }}
- name: REDIS_PORT
value: {{ .Values.redis.port | quote }}
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "web-app.fullname" . }}
key: redis-password
- name: REDIS_DATABASE
value: {{ .Values.redis.database | quote }}
{{- end }}
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumeMounts:
- name: config
mountPath: /app/config
readOnly: true
volumes:
- name: config
configMap:
name: {{ include "web-app.fullname" . }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
# 4. templates/service.yaml
apiVersion: v1
kind: Service
metadata:
name: {{ include "web-app.fullname" . }}
labels:
{{- include "web-app.labels" . | nindent 4 }}
{{- with .Values.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "web-app.selectorLabels" . | nindent 4 }}
# 5. templates/ingress.yaml
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "web-app.fullname" . }}
labels:
{{- include "web-app.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
ingressClassName: {{ .Values.ingress.className }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if .pathType }}
pathType: {{ .pathType }}
{{- end }}
backend:
service:
name: {{ include "web-app.fullname" $ }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}
{{- end }}
# 6. templates/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "web-app.fullname" . }}
labels:
{{- include "web-app.labels" . | nindent 4 }}
data:
app.json: |
{
"environment": "{{ .Values.app.env }}",
"logLevel": "{{ .Values.app.logLevel }}",
"features": {{ .Values.app.features | toJson }}
}
{{- if .Values.database.enabled }}
database.json: |
{
"host": "{{ .Values.database.host }}",
"port": {{ .Values.database.port }},
"name": "{{ .Values.database.name }}",
"user": "{{ .Values.database.user }}",
"sslMode": "{{ .Values.database.sslMode }}"
}
{{- end }}
nginx.conf: |
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
location /ready {
access_log off;
return 200 "ready\n";
add_header Content-Type text/plain;
}
}
# 7. templates/secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: {{ include "web-app.fullname" . }}
labels:
{{- include "web-app.labels" . | nindent 4 }}
type: Opaque
data:
{{- if .Values.database.enabled }}
database-password: {{ .Values.database.password | b64enc | quote }}
{{- end }}
{{- if .Values.redis.enabled }}
redis-password: {{ .Values.redis.password | b64enc | quote }}
{{- end }}
# 8. templates/hpa.yaml
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "web-app.fullname" . }}
labels:
{{- include "web-app.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "web-app.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}
# 9. templates/_helpers.tpl - Helper Templates
{{/*
Expand the name of the chart.
*/}}
{{- define "web-app.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "web-app.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "web-app.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "web-app.labels" -}}
helm.sh/chart: {{ include "web-app.chart" . }}
{{ include "web-app.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "web-app.selectorLabels" -}}
app.kubernetes.io/name: {{ include "web-app.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "web-app.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "web-app.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
# 10. templates/NOTES.txt - Installation Notes
{{- /*
Notes displayed after chart installation
*/}}
{{- if .Values.ingress.enabled }}
Your web application has been deployed!
{{- range .Values.ingress.hosts }}
Access your application at: {{- if .tls }}https{{ else }}http{{- end }}://{{ .host | quote }}
{{- end }}
{{- else }}
Your web application has been deployed!
Get the application URL by running these commands:
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "web-app.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}
💻 Helm Chart de Aplicação Microservices
🟡 intermediate
⭐⭐⭐⭐
Configuração completa de microservices com múltiplos serviços, dependências compartilhadas e configurações avançadas
⏱️ 30 min
🏷️ helm, microservices, kubernetes, dependencies
Prerequisites:
Helm basics, Kubernetes services, Microservices architecture
# Microservices Application Helm Chart
# Complete setup for multiple interconnected services
# 1. Chart.yaml
apiVersion: v2
name: microservices-app
description: A Helm chart for microservices application
type: application
version: 2.0.0
appVersion: "2.0.0"
dependencies:
- name: postgresql
version: 12.x.x
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled
- name: redis
version: 17.x.x
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled
- name: elasticsearch
version: 19.x.x
repository: https://charts.bitnami.com/bitnami
condition: elasticsearch.enabled
# 2. values.yaml
global:
imageRegistry: ""
imagePullSecrets: []
storageClass: ""
# Common configurations
common:
annotations: {}
labels: {}
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
# API Gateway Configuration
gateway:
enabled: true
replicaCount: 2
image:
repository: myregistry/api-gateway
tag: "2.0.0"
pullPolicy: IfNotPresent
service:
type: LoadBalancer
port: 80
targetPort: 8080
ingress:
enabled: true
className: nginx
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
hosts:
- host: api.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: api-tls
hosts:
- api.example.com
env:
- name: LOG_LEVEL
value: "INFO"
- name: RATE_LIMIT
value: "100"
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 70
nodeSelector:
node-type: edge
tolerations: []
# User Service
userService:
enabled: true
replicaCount: 2
image:
repository: myregistry/user-service
tag: "2.0.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 3001
targetPort: 3001
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: postgres-secret
key: url
- name: REDIS_URL
valueFrom:
secretKeyRef:
name: redis-secret
key: url
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 8
targetCPUUtilizationPercentage: 75
# Order Service
orderService:
enabled: true
replicaCount: 2
image:
repository: myregistry/order-service
tag: "2.0.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 3002
targetPort: 3002
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: postgres-secret
key: url
- name: USER_SERVICE_URL
value: "http://user-service:3001"
- name: NOTIFICATION_SERVICE_URL
value: "http://notification-service:3003"
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 6
targetCPUUtilizationPercentage: 70
# Payment Service
paymentService:
enabled: true
replicaCount: 2
image:
repository: myregistry/payment-service
tag: "2.0.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 3004
targetPort: 3004
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: postgres-secret
key: url
- name: STRIPE_API_KEY
valueFrom:
secretKeyRef:
name: payment-secrets
key: stripe-key
resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
# Notification Service
notificationService:
enabled: true
replicaCount: 1
image:
repository: myregistry/notification-service
tag: "2.0.0"
pullPolicy: IfNotPresent
service:
type: ClusterIP
port: 3003
targetPort: 3003
env:
- name: SMTP_HOST
value: "smtp.example.com"
- name: SMTP_USER
valueFrom:
secretKeyRef:
name: smtp-secrets
key: username
- name: SMTP_PASSWORD
valueFrom:
secretKeyRef:
name: smtp-secrets
key: password
# PostgreSQL Configuration
postgresql:
enabled: true
auth:
postgresPassword: "postgres123"
username: "microservices"
password: "microservices123"
database: "microservices"
primary:
persistence:
enabled: true
size: 20Gi
storageClass: fast-ssd
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
readReplicas:
replicaCount: 2
persistence:
enabled: true
size: 20Gi
# Redis Configuration
redis:
enabled: true
auth:
enabled: true
password: "redis123"
master:
persistence:
enabled: true
size: 8Gi
resources:
limits:
cpu: 500m
memory: 512Mi
replica:
replicaCount: 2
persistence:
enabled: true
size: 8Gi
# Elasticsearch Configuration
elasticsearch:
enabled: false
replicas: 3
minimumMasterNodes: 2
volumeClaimTemplate:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 30Gi
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 1Gi
# Monitoring Configuration
monitoring:
enabled: true
prometheus:
enabled: true
serviceMonitor:
enabled: true
namespace: monitoring
labels:
release: prometheus
interval: 30s
scrapeTimeout: 10s
grafana:
enabled: false
service:
type: LoadBalancer
port: 3000
# Jaeger Tracing
jaeger:
enabled: false
provisionDataStore:
cassandra: false
elasticsearch: true
elasticsearch:
client:
url: "http://elasticsearch:9200"
# Service Mesh (Istio)
istio:
enabled: false
gateways:
enabled: true
hosts:
- api.example.com
virtualServices:
enabled: true
destinationRules:
enabled: true
# 3. templates/_helpers.tpl - Extended Helper Templates
{{/*
Common labels for microservices
*/}}
{{- define "microservices-app.labels" -}}
helm.sh/chart: {{ include "microservices-app.chart" . }}
{{ include "microservices-app.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels for microservices
*/}}
{{- define "microservices-app.selectorLabels" -}}
app.kubernetes.io/name: {{ include "microservices-app.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/component: {{ .component | default "service" }}
{{- end }}
{{/*
Service name for microservices
*/}}
{{- define "microservices-app.serviceName" -}}
{{- $component := .component -}}
{{- $fullName := include "microservices-app.fullname" . -}}
{{- if eq $component "gateway" -}}
{{- $fullName -}}
{{- else -}}
{{- printf "%s-%s" $fullName $component -}}
{{- end -}}
{{- end }}
{{/*
Database connection URL
*/}}
{{- define "microservices-app.databaseURL" -}}
{{- if .Values.postgresql.enabled -}}
postgresql://{{ .Values.postgresql.auth.username }}:{{ .Values.postgresql.auth.password }}@{{ .Release.Name }}-postgresql.{{ .Release.Namespace }}.svc.cluster.local:5432/{{ .Values.postgresql.auth.database }}
{{- else -}}
{{- .Values.externalDatabase.url | default "" -}}
{{- end -}}
{{- end }}
{{/*
Redis connection URL
*/}}
{{- define "microservices-app.redisURL" -}}
{{- if .Values.redis.enabled -}}
redis://:{{ .Values.redis.auth.password }}@{{ .Release.Name }}-redis-master.{{ .Release.Namespace }}.svc.cluster.local:6379/{{ .Values.redis.database | default "0" }}
{{- else -}}
{{- .Values.externalRedis.url | default "" -}}
{{- end -}}
{{- end }}
# 4. templates/gateway/deployment.yaml
{{- if .Values.gateway.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "microservices-app.fullname" . }}-gateway
labels:
{{- include "microservices-app.labels" . | nindent 4 }}
app.kubernetes.io/component: gateway
spec:
replicas: {{ .Values.gateway.replicaCount }}
selector:
matchLabels:
{{- include "microservices-app.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: gateway
template:
metadata:
labels:
{{- include "microservices-app.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: gateway
annotations:
checksum/config: {{ include (print $.Template.BasePath "/gateway/configmap.yaml") . | sha256sum }}
spec:
containers:
- name: gateway
image: "{{ .Values.gateway.image.repository }}:{{ .Values.gateway.image.tag }}"
imagePullPolicy: {{ .Values.gateway.image.pullPolicy }}
ports:
- name: http
containerPort: 8080
protocol: TCP
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: http
initialDelaySeconds: 5
periodSeconds: 5
env:
{{- range .Values.gateway.env }}
- name: {{ .name }}
value: {{ .value | quote }}
{{- end }}
- name: USER_SERVICE_URL
value: "http://{{ include "microservices-app.serviceName" (dict "component" "userService" "context" $) }}:{{ .Values.userService.service.port }}"
- name: ORDER_SERVICE_URL
value: "http://{{ include "microservices-app.serviceName" (dict "component" "orderService" "context" $) }}:{{ .Values.orderService.service.port }}"
- name: PAYMENT_SERVICE_URL
value: "http://{{ include "microservices-app.serviceName" (dict "component" "paymentService" "context" $) }}:{{ .Values.paymentService.service.port }}"
- name: NOTIFICATION_SERVICE_URL
value: "http://{{ include "microservices-app.serviceName" (dict "component" "notificationService" "context" $) }}:{{ .Values.notificationService.service.port }}"
resources:
{{- toYaml .Values.common.resources | nindent 12 }}
volumeMounts:
- name: config
mountPath: /app/config
readOnly: true
volumes:
- name: config
configMap:
name: {{ include "microservices-app.fullname" . }}-gateway
{{- end }}
# 5. templates/gateway/service.yaml
{{- if .Values.gateway.enabled }}
apiVersion: v1
kind: Service
metadata:
name: {{ include "microservices-app.serviceName" (dict "component" "gateway" "context" .) }}
labels:
{{- include "microservices-app.labels" . | nindent 4 }}
app.kubernetes.io/component: gateway
{{- with .Values.gateway.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.gateway.service.type }}
ports:
- port: {{ .Values.gateway.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "microservices-app.selectorLabels" . | nindent 4 }}
app.kubernetes.io/component: gateway
{{- end }}
# 6. templates/gateway/ingress.yaml
{{- if and .Values.gateway.enabled .Values.gateway.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "microservices-app.fullname" . }}-gateway
labels:
{{- include "microservices-app.labels" . | nindent 4 }}
app.kubernetes.io/component: gateway
{{- with .Values.gateway.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
ingressClassName: {{ .Values.gateway.ingress.className }}
{{- if .Values.gateway.ingress.tls }}
tls:
{{- range .Values.gateway.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.gateway.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if .pathType }}
pathType: {{ .pathType }}
{{- end }}
backend:
service:
name: {{ include "microservices-app.serviceName" (dict "component" "gateway" "context" $) }}
port:
number: {{ $.Values.gateway.service.port }}
{{- end }}
{{- end }}
{{- end }}
# 7. templates/shared/secrets.yaml
apiVersion: v1
kind: Secret
metadata:
name: postgres-secret
labels:
{{- include "microservices-app.labels" . | nindent 4 }}
type: Opaque
data:
url: {{ include "microservices-app.databaseURL" . | b64enc | quote }}
---
apiVersion: v1
kind: Secret
metadata:
name: redis-secret
labels:
{{- include "microservices-app.labels" . | nindent 4 }}
type: Opaque
data:
url: {{ include "microservices-app.redisURL" . | b64enc | quote }}
---
apiVersion: v1
kind: Secret
metadata:
name: payment-secrets
labels:
{{- include "microservices-app.labels" . | nindent 4 }}
type: Opaque
data:
stripe-key: {{ .Values.paymentService.stripeApiKey | default "" | b64enc | quote }}
---
apiVersion: v1
kind: Secret
metadata:
name: smtp-secrets
labels:
{{- include "microservices-app.labels" . | nindent 4 }}
type: Opaque
data:
username: {{ .Values.notificationService.smtpUsername | default "" | b64enc | quote }}
password: {{ .Values.notificationService.smtpPassword | default "" | b64enc | quote }}
# 8. templates/monitoring/servicemonitor.yaml
{{- if .Values.monitoring.enabled }}
{{- range $service := list "gateway" "userService" "orderService" "paymentService" "notificationService" }}
{{- if (index $.Values $service "enabled") }}
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ include "microservices-app.fullname" $ }}-{{ $service }}
labels:
{{- include "microservices-app.labels" $ | nindent 4 }}
app.kubernetes.io/component: {{ $service }}
{{- with $.Values.monitoring.prometheus.serviceMonitor.labels }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
selector:
matchLabels:
{{- include "microservices-app.selectorLabels" $ | nindent 6 }}
app.kubernetes.io/component: {{ $service }}
namespaceSelector:
any: true
endpoints:
- port: http
interval: {{ $.Values.monitoring.prometheus.serviceMonitor.interval }}
scrapeTimeout: {{ $.Values.monitoring.prometheus.serviceMonitor.scrapeTimeout }}
path: /metrics
{{- end }}
{{- end }}
{{- end }}
# 9. templates/istio/gateway.yaml (if Istio enabled)
{{- if .Values.istio.enabled }}
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: {{ include "microservices-app.fullname" . }}-gateway
labels:
{{- include "microservices-app.labels" . | nindent 4 }}
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
{{- range .Values.istio.gateways.hosts }}
- {{ . }}
{{- end }}
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: {{ include "microservices-app.fullname" . }}-tls
hosts:
{{- range .Values.istio.gateways.hosts }}
- {{ . }}
{{- end }}
---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: {{ include "microservices-app.fullname" . }}
labels:
{{- include "microservices-app.labels" . | nindent 4 }}
spec:
hosts:
{{- range .Values.istio.gateways.hosts }}
- {{ . }}
{{- end }}
gateways:
- {{ include "microservices-app.fullname" . }}-gateway
http:
- match:
- uri:
prefix: /api/users
rewrite:
uri: /
route:
- destination:
host: {{ include "microservices-app.serviceName" (dict "component" "userService" "context" .) }}
port:
number: {{ .Values.userService.service.port }}
- match:
- uri:
prefix: /api/orders
rewrite:
uri: /
route:
- destination:
host: {{ include "microservices-app.serviceName" (dict "component" "orderService" "context" .) }}
port:
number: {{ .Values.orderService.service.port }}
- match:
- uri:
prefix: /api/payments
rewrite:
uri: /
route:
- destination:
host: {{ include "microservices-app.serviceName" (dict "component" "paymentService" "context" .) }}
port:
number: {{ .Values.paymentService.service.port }}
{{- end }}
# 10. Chart.lock (dependency lock file)
dependencies:
- name: postgresql
version: 12.1.9
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled
- name: redis
version: 17.3.7
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled
- name: elasticsearch
version: 19.5.0
repository: https://charts.bitnami.com/bitnami
condition: elasticsearch.enabled
digest: sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
💻 Helm Chart Empresarial Avançado
🔴 complex
⭐⭐⭐⭐⭐
Helm chart pronto para produção com segurança, conformidade, monitoramento e suporte multi-ambiente
⏱️ 45 min
🏷️ helm, enterprise, security, compliance, production
Prerequisites:
Advanced Helm, Enterprise security, Compliance standards, Multi-environment deployment
# Enterprise-Grade Helm Chart
# Production-ready with security, compliance, and multi-environment support
# 1. Chart.yaml
apiVersion: v2
name: enterprise-app
description: Production-ready enterprise application Helm chart
type: application
version: 3.0.0
appVersion: "3.0.0"
home: https://github.company.com/enterprise-app
sources:
- https://github.company.com/enterprise-app
dependencies:
- name: postgresql
version: 12.x.x
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled
- name: redis
version: 17.x.x
repository: https://charts.bitnami.com/bitnami
condition: redis.enabled
- name: keycloak
version: 18.x.x
repository: https://codecentric.github.io/helm-charts
condition: keycloak.enabled
- name: prometheus-operator
version: 45.x.x
repository: https://prometheus-community.github.io/helm-charts
condition: monitoring.prometheus.enabled
- name: elasticsearch
version: 19.x.x
repository: https://helm.elastic.co
condition: logging.elasticsearch.enabled
# 2. values.yaml
# Global settings
global:
# Environment (dev, staging, prod)
environment: production
# Image registry and pull policy
imageRegistry: "registry.company.com"
imagePullSecrets:
- name: registry-secret
imagePullPolicy: IfNotPresent
# Common labels and annotations
labels:
team: platform
cost-center: engineering
compliance-level: high
annotations:
contact: [email protected]
cost-optimization: enabled
# Resource defaults
resources:
default:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
small:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 256Mi
medium:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 1000m
memory: 1Gi
large:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
# Application Configuration
app:
name: enterprise-app
# Repository and image configuration
image:
repository: enterprise-app
tag: "3.0.0"
pullPolicy: IfNotPresent
# Deployment configuration
replicaCount: 3
# Resource class (small, medium, large)
resourceClass: medium
# Environment-specific configurations
environments:
dev:
replicaCount: 1
resourceClass: small
debug: true
staging:
replicaCount: 2
resourceClass: medium
debug: false
prod:
replicaCount: 5
resourceClass: large
debug: false
priorityClassName: high-priority
# Security Configuration
security:
# Pod Security Standards
podSecurityPolicy:
enabled: true
privileged: false
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
capabilities:
drop:
- ALL
# Network policies
networkPolicy:
enabled: true
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
- from:
- namespaceSelector:
matchLabels:
name: monitoring
egress:
- to: []
- to: []
ports:
- protocol: TCP
port: 53
- protocol: UDP
port: 53
# RBAC
rbac:
enabled: true
serviceAccount:
create: true
name: ""
annotations:
iam.amazonaws.com/role: "arn:aws:iam::123456789012:role/enterprise-app-role"
# Admission controllers
admissionWebhooks:
enabled: true
validatePodSecurity: true
enforceResourceQuotas: true
# High Availability
highAvailability:
# Pod disruption budget
podDisruptionBudget:
enabled: true
minAvailable: 2
maxUnavailable: 1
# Anti-affinity rules
antiAffinity:
enabled: true
type: hard # soft or hard
topologyKey: kubernetes.io/hostname
# Zone distribution
zoneDistribution:
enabled: true
zones:
- us-west-2a
- us-west-2b
- us-west-2c
# Autoscaling
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 20
targetCPUUtilizationPercentage: 70
targetMemoryUtilizationPercentage: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 0
policies:
- type: Percent
value: 100
periodSeconds: 15
- type: Pods
value: 4
periodSeconds: 15
selectPolicy: Max
# Database Configuration
postgresql:
enabled: true
auth:
postgresPassword: "" # Use external secret
username: enterpriseapp
password: "" # Use external secret
database: enterpriseapp
primary:
persistence:
enabled: true
size: 100Gi
storageClass: ssd-fast
accessModes: ["ReadWriteOnce"]
resources:
requests:
cpu: 1000m
memory: 4Gi
limits:
cpu: 2000m
memory: 8Gi
configuration: |
max_connections = 200
shared_buffers = 1GB
effective_cache_size = 3GB
maintenance_work_mem = 256MB
checkpoint_completion_target = 0.9
wal_buffers = 16MB
default_statistics_target = 100
random_page_cost = 1.1
effective_io_concurrency = 200
readReplicas:
replicaCount: 2
persistence:
enabled: true
size: 100Gi
storageClass: ssd-fast
resources:
requests:
cpu: 500m
memory: 2Gi
limits:
cpu: 1000m
memory: 4Gi
backup:
enabled: true
schedule: "0 2 * * *" # Daily at 2 AM
retention: "30d"
storageClass: backup
# Redis Configuration
redis:
enabled: true
auth:
enabled: true
password: "" # Use external secret
master:
persistence:
enabled: true
size: 20Gi
storageClass: ssd-fast
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1000m
memory: 2Gi
configuration: |
maxmemory 1gb
maxmemory-policy allkeys-lru
save 900 1
save 300 10
save 60 10000
replica:
replicaCount: 2
persistence:
enabled: true
size: 20Gi
storageClass: ssd-fast
# Authentication (Keycloak)
keycloak:
enabled: true
auth:
adminUser: admin
adminPassword: "" # Use external secret
postgresql:
enabled: false
externalDatabase:
host: "{{ .Release.Name }}-postgresql"
port: 5432
user: "{{ .Values.postgresql.auth.username }}"
password: "{{ .Values.postgresql.auth.password }}"
database: keycloak
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1000m
memory: 2Gi
extraEnv: |
- name: JAVA_OPTS
value: >-
-Xms512m -Xmx1024m
-XX:+UseG1GC
-XX:+UseContainerSupport
-XX:MaxRAMPercentage=75.0
# Monitoring
monitoring:
prometheus:
enabled: true
serviceMonitor:
enabled: true
namespace: monitoring
interval: 30s
scrapeTimeout: 10s
labels:
team: platform
environment: "{{ .Values.global.environment }}"
annotations:
prometheus.io/scrape: "true"
prometheus.io/path: "/metrics"
prometheus.io/port: "9090"
rules:
enabled: true
alertingRules:
- name: app-down
expr: up{job="{{ .Release.Name }}"} == 0
for: 1m
labels:
severity: critical
team: platform
annotations:
summary: "{{ .Release.Name }} is down"
description: "{{ .Release.Name }} has been down for more than 1 minute."
grafana:
enabled: true
service:
type: LoadBalancer
port: 3000
adminPassword: "" # Use external secret
dashboards:
enabled: true
default:
- enterprise-app-overview
- enterprise-app-performance
jaeger:
enabled: true
provisionDataStore:
cassandra: false
elasticsearch: true
elasticsearch:
client:
url: "http://elasticsearch:9200"
agent:
enabled: true
collector:
enabled: true
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 1Gi
# Logging
logging:
elasticsearch:
enabled: true
replicas: 3
volumeClaimTemplate:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 50Gi
resources:
requests:
cpu: 1000m
memory: 2Gi
limits:
cpu: 2000m
memory: 4Gi
minimumMasterNodes: 2
kibana:
enabled: true
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 500m
memory: 1Gi
elasticsearchHosts: "http://elasticsearch:9200"
logstash:
enabled: false
replicas: 1
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: 500m
memory: 1Gi
fluentd:
enabled: true
resources:
requests:
cpu: 100m
memory: 200Mi
limits:
cpu: 200m
memory: 400Mi
# Cost Optimization
costOptimization:
# Spot instances (for non-critical workloads)
spotInstances:
enabled: false
tolerations:
- key: "spot-instance"
operator: "Equal"
value: "true"
effect: "NoSchedule"
nodeSelector:
node-lifecycle: spot
# Resource requests optimization
rightSizing:
enabled: true
recommendations: true
autoApply: false # Manual review required
# Scaledown for non-working hours
scheduledScaling:
enabled: false
timezone: "America/Los_Angeles"
schedules:
- name: business-hours
start: "08:00"
end: "18:00"
days: ["monday", "tuesday", "wednesday", "thursday", "friday"]
minReplicas: 2
maxReplicas: 10
- name: after-hours
start: "18:01"
end: "07:59"
days: ["monday", "tuesday", "wednesday", "thursday", "friday"]
minReplicas: 1
maxReplicas: 3
# Backup and Disaster Recovery
backup:
enabled: true
schedule: "0 2 * * *" # Daily at 2 AM
retention: "30d"
storage:
type: s3
s3:
bucket: "company-backups"
region: "us-west-2"
prefix: "enterprise-app"
storageClass: "STANDARD_IA"
encryption:
enabled: true
type: AES256
disasterRecovery:
enabled: true
crossRegion:
enabled: true
sourceRegion: "us-west-2"
targetRegion: "us-east-1"
targetBucket: "company-backups-dr"
# Compliance and Auditing
compliance:
# PCI DSS compliance
pci:
enabled: true
encryptionAtRest: true
encryptionInTransit: true
accessControl: true
auditLogging: true
# GDPR compliance
gdpr:
enabled: true
dataRetention: "2555d" # 7 years
rightToErasure: true
consentManagement: true
# SOX compliance
sox:
enabled: true
auditTrail: true
changeManagement: true
segregationOfDuties: true
# HIPAA compliance (if applicable)
hipaa:
enabled: false
phiEncryption: true
accessLogs: true
businessAssociateAgreement: true
# Environment-specific values
environments:
dev:
global:
environment: dev
app:
replicaCount: 1
resourceClass: small
postgresql:
primary:
persistence:
size: 10Gi
readReplicas:
replicaCount: 0
monitoring:
prometheus:
enabled: false
backup:
enabled: false
compliance:
pci:
enabled: false
gdpr:
enabled: false
sox:
enabled: false
staging:
global:
environment: staging
app:
replicaCount: 2
resourceClass: medium
postgresql:
primary:
persistence:
size: 50Gi
readReplicas:
replicaCount: 1
backup:
enabled: true
schedule: "0 3 * * *"
compliance:
pci:
enabled: true
gdpr:
enabled: true
sox:
enabled: false
prod:
global:
environment: prod
app:
replicaCount: 5
resourceClass: large
postgresql:
primary:
persistence:
size: 500Gi
readReplicas:
replicaCount: 3
highAvailability:
podDisruptionBudget:
minAvailable: 3
antiAffinity:
type: hard
zoneDistribution:
enabled: true
backup:
enabled: true
schedule: "0 1 * * *"
retention: "90d"
compliance:
pci:
enabled: true
gdpr:
enabled: true
sox:
enabled: true
costOptimization:
spotInstances:
enabled: false
scheduledScaling:
enabled: true
# 3. Chart Templates (examples)
# templates/_helpers.tpl - Advanced helper functions
{{/*
Get resource limits based on class and environment
*/}}
{{- define "enterprise-app.resources" -}}
{{- $resourceClass := .Values.app.resourceClass | default "default" -}}
{{- $env := .Values.global.environment | default "dev" -}}
{{- $baseResources := index .Values.global.resources $resourceClass -}}
{{- $envConfig := index .Values.app.environments $env -}}
{{- $envResourceClass := $envConfig.resourceClass | default $resourceClass -}}
{{- $envResources := index .Values.global.resources $envResourceClass -}}
{{- $finalResources := dict -}}
{{- range $key, $value := $baseResources.requests -}}
{{- $_ := set $finalResources "requests" (dict $key (max ($value | int) (index ($envResources.requests | default dict) $key | int))) -}}
{{- end -}}
{{- range $key, $value := $baseResources.limits -}}
{{- $_ := set $finalResources "limits" (dict $key (max ($value | int) (index ($envResources.limits | default dict) $key | int))) -}}
{{- end -}}
{{- toYaml $finalResources -}}
{{- end }}
{{/*
Generate security context based on compliance requirements
*/}}
{{- define "enterprise-app.securityContext" -}}
{{- $securityContext := .Values.security.podSecurityPolicy -}}
{{- if .Values.compliance.pci.enabled -}}
{{- $_ := set $securityContext "readOnlyRootFilesystem" true -}}
{{- $_ := set $securityContext "runAsNonRoot" true -}}
{{- $_ := set $securityContext "capabilities" (dict "drop" (list "ALL")) -}}
{{- end -}}
{{- toYaml $securityContext -}}
{{- end }}
{{/*
Generate affinity rules for high availability
*/}}
{{- define "enterprise-app.affinity" -}}
{{- if .Values.highAvailability.antiAffinity.enabled -}}
{{- $antiAffinity := .Values.highAvailability.antiAffinity -}}
{{- if eq $antiAffinity.type "hard" -}}
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
{{- include "enterprise-app.selectorLabels" . | nindent 8 }}
topologyKey: {{ $antiAffinity.topologyKey | default "kubernetes.io/hostname" }}
{{- else -}}
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
{{- include "enterprise-app.selectorLabels" . | nindent 10 }}
topologyKey: {{ $antiAffinity.topologyKey | default "kubernetes.io/hostname" }}
{{- end -}}
{{- if .Values.highAvailability.zoneDistribution.enabled -}}
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values: {{ .Values.highAvailability.zoneDistribution.zones | toYaml }}
{{- end -}}
{{- end -}}
{{- end }}
{{/*
Generate compliance annotations
*/}}
{{- define "enterprise-app.complianceAnnotations" -}}
{{- $annotations := dict -}}
{{- if .Values.compliance.pci.enabled -}}
{{- $_ := set $annotations "pci-dss.compliance" "enabled" -}}
{{- $_ := set $annotations "pci-dss.version" "4.0" -}}
{{- end -}}
{{- if .Values.compliance.gdpr.enabled -}}
{{- $_ := set $annotations "gdpr.compliance" "enabled" -}}
{{- $_ := set $annotations "data-retention.days" .Values.compliance.gdpr.dataRetention -}}
{{- end -}}
{{- if .Values.compliance.sox.enabled -}}
{{- $_ := set $annotations "sox.compliance" "enabled" -}}
{{- $_ := set $annotations "audit-trail" "enabled" -}}
{{- end -}}
{{- toYaml $annotations -}}
{{- end }}
# 4. Templates for advanced features
# templates/security/networkpolicy.yaml
{{- if .Values.security.networkPolicy.enabled }}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: {{ include "enterprise-app.fullname" . }}
labels:
{{- include "enterprise-app.labels" . | nindent 4 }}
spec:
podSelector:
matchLabels:
{{- include "enterprise-app.selectorLabels" . | nindent 6 }}
policyTypes:
- Ingress
- Egress
ingress:
{{- range .Values.security.networkPolicy.ingress }}
- from:
{{- toYaml .from | nindent 6 }}
{{- if .ports }}
ports:
{{- toYaml .ports | nindent 6 }}
{{- end }}
{{- end }}
egress:
{{- range .Values.security.networkPolicy.egress }}
- to:
{{- toYaml .to | nindent 6 }}
{{- if .ports }}
ports:
{{- toYaml .ports | nindent 6 }}
{{- end }}
{{- end }}
{{- end }}
# templates/cost-optimization/scheduled-scaling.yaml
{{- if .Values.costOptimization.scheduledScaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "enterprise-app.fullname" . }}-scheduled
labels:
{{- include "enterprise-app.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "enterprise-app.fullname" . }}
minReplicas: {{ .Values.costOptimization.scheduledScaling.schedules[0].minReplicas }}
maxReplicas: {{ .Values.costOptimization.scheduledScaling.schedules[0].maxReplicas }}
metrics:
- type: External
external:
metric:
name: scheduled_replicas
target:
type: AverageValue
averageValue: "1"
{{- end }}
# templates/compliance/audit-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "enterprise-app.fullname" . }}-audit-config
labels:
{{- include "enterprise-app.labels" . | nindent 4 }}
annotations:
{{- include "enterprise-app.complianceAnnotations" . | nindent 4 }}
data:
audit.conf: |
# Audit configuration
log_level: {{ .Values.global.environment | default "production" }}
audit_enabled: {{ .Values.compliance.sox.auditTrail | default "true" }}
encryption_at_rest: {{ .Values.compliance.pci.encryptionAtRest | default "true" }}
data_retention_days: {{ .Values.compliance.gdpr.dataRetention | default "2555" }}
# PCI DSS requirements
pci_compliance: {{ .Values.compliance.pci.enabled | default "false" }}
encryption_in_transit: {{ .Values.compliance.pci.encryptionInTransit | default "true" }}
# Access control
rbac_enabled: {{ .Values.security.rbac.enabled | default "true" }}
mfa_required: {{ .Values.compliance.sox.segregationOfDuties | default "true" }}
# templates/disaster-recovery/restore-job.yaml
{{- if .Values.backup.disasterRecovery.enabled }}
apiVersion: batch/v1
kind: Job
metadata:
name: {{ include "enterprise-app.fullname" . }}-disaster-recovery
labels:
{{- include "enterprise-app.labels" . | nindent 4 }}
app.kubernetes.io/component: disaster-recovery
annotations:
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "1"
"helm.sh/hook-delete-policy": hook-succeeded
spec:
template:
metadata:
labels:
{{- include "enterprise-app.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: disaster-recovery
spec:
restartPolicy: Never
containers:
- name: disaster-recovery
image: "registry.company.com/disaster-recovery:latest"
command:
- /bin/bash
- -c
- |
echo "Starting disaster recovery process..."
# Restore from cross-region backup
aws s3 sync s3://{{ .Values.backup.storage.s3.bucket }}-dr/enterprise-app/ s3://{{ .Values.backup.storage.s3.bucket }}/enterprise-app/ --region {{ .Values.backup.storage.s3.region }}
# Restore database
pg_restore -h {{ .Release.Name }}-postgresql -U {{ .Values.postgresql.auth.username }} -d {{ .Values.postgresql.auth.database }} /tmp/latest-backup.sql
echo "Disaster recovery completed successfully!"
env:
- name: AWS_DEFAULT_REGION
value: {{ .Values.backup.storage.s3.region | quote }}
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1000m
memory: 2Gi
{{- end }}
# 5. Environment-specific values files
# values-dev.yaml
global:
environment: dev
imagePullPolicy: Always
app:
replicaCount: 1
resourceClass: small
postgresql:
primary:
persistence:
size: 10Gi
readReplicas:
replicaCount: 0
monitoring:
prometheus:
enabled: false
backup:
enabled: false
compliance:
pci:
enabled: false
gdpr:
enabled: false
sox:
enabled: false
# values-prod.yaml
global:
environment: prod
imagePullPolicy: IfNotPresent
app:
replicaCount: 5
resourceClass: large
highAvailability:
podDisruptionBudget:
minAvailable: 3
antiAffinity:
type: hard
zoneDistribution:
enabled: true
zones:
- us-west-2a
- us-west-2b
- us-west-2c
postgresql:
primary:
persistence:
size: 500Gi
readReplicas:
replicaCount: 3
backup:
enabled: true
schedule: "0 1 * * *"
retention: "90d"
compliance:
pci:
enabled: true
gdpr:
enabled: true
sox:
enabled: true
costOptimization:
spotInstances:
enabled: false
scheduledScaling:
enabled: true