1035 lines
23 KiB
Markdown
1035 lines
23 KiB
Markdown
---
|
|
template_id: "deployment-guide-comprehensive"
|
|
template_name: "Comprehensive Deployment Guide Template"
|
|
version: "1.0.0"
|
|
category: "persona"
|
|
personas: ["devops-documentation-specialist", "cross-platform-integration-specialist"]
|
|
technologies: ["docker", "kubernetes", "azure", "aws", "nodejs", "aspnet", "react"]
|
|
complexity: "advanced"
|
|
estimated_time: "120-180 minutes"
|
|
dependencies: ["technical-architecture", "infrastructure-design"]
|
|
tags: ["deployment", "devops", "infrastructure", "containerization", "cloud"]
|
|
---
|
|
|
|
# Deployment Guide: {{PROJECT_NAME}}
|
|
|
|
## Deployment Overview
|
|
**Project:** {{PROJECT_NAME}}
|
|
**Environment:** {{TARGET_ENVIRONMENT}}
|
|
**Platform:** {{DEPLOYMENT_PLATFORM}}
|
|
**Technology Stack:** {{TECHNOLOGY_STACK}}
|
|
**Deployment Method:** {{DEPLOYMENT_METHOD}}
|
|
**Last Updated:** {{LAST_UPDATED}}
|
|
|
|
### Deployment Summary
|
|
{{DEPLOYMENT_SUMMARY_DESCRIPTION}}
|
|
|
|
### Prerequisites
|
|
- {{PREREQUISITE_1}}
|
|
- {{PREREQUISITE_2}}
|
|
- {{PREREQUISITE_3}}
|
|
|
|
## Architecture Overview
|
|
|
|
### Deployment Architecture Diagram
|
|
```mermaid
|
|
graph TB
|
|
subgraph "Load Balancer"
|
|
LB[Azure Load Balancer]
|
|
end
|
|
|
|
subgraph "Web Tier"
|
|
W1[React App Instance 1]
|
|
W2[React App Instance 2]
|
|
end
|
|
|
|
subgraph "API Tier"
|
|
A1[Node.js API Instance 1]
|
|
A2[Node.js API Instance 2]
|
|
A3[ASP.NET API Instance 1]
|
|
A4[ASP.NET API Instance 2]
|
|
end
|
|
|
|
subgraph "Data Tier"
|
|
DB[(PostgreSQL)]
|
|
CACHE[(Redis Cache)]
|
|
end
|
|
|
|
LB --> W1
|
|
LB --> W2
|
|
W1 --> A1
|
|
W1 --> A3
|
|
W2 --> A2
|
|
W2 --> A4
|
|
A1 --> DB
|
|
A2 --> DB
|
|
A3 --> DB
|
|
A4 --> DB
|
|
A1 --> CACHE
|
|
A2 --> CACHE
|
|
A3 --> CACHE
|
|
A4 --> CACHE
|
|
```
|
|
|
|
### Component Distribution
|
|
- **Frontend:** {{FRONTEND_DEPLOYMENT_DETAILS}}
|
|
- **Backend APIs:** {{BACKEND_DEPLOYMENT_DETAILS}}
|
|
- **Database:** {{DATABASE_DEPLOYMENT_DETAILS}}
|
|
- **Cache:** {{CACHE_DEPLOYMENT_DETAILS}}
|
|
|
|
## Environment Configuration
|
|
|
|
### Development Environment
|
|
\```yaml
|
|
# docker-compose.dev.yml
|
|
version: '3.8'
|
|
services:
|
|
frontend:
|
|
build:
|
|
context: ./frontend
|
|
dockerfile: Dockerfile.dev
|
|
ports:
|
|
- "3000:3000"
|
|
environment:
|
|
- NODE_ENV=development
|
|
- REACT_APP_API_URL=http://localhost:5000
|
|
volumes:
|
|
- ./frontend:/app
|
|
- /app/node_modules
|
|
|
|
nodejs-api:
|
|
build:
|
|
context: ./backend/nodejs
|
|
dockerfile: Dockerfile.dev
|
|
ports:
|
|
- "5000:5000"
|
|
environment:
|
|
- NODE_ENV=development
|
|
- DATABASE_URL={{DEV_DATABASE_URL}}
|
|
- REDIS_URL={{DEV_REDIS_URL}}
|
|
volumes:
|
|
- ./backend/nodejs:/app
|
|
- /app/node_modules
|
|
|
|
aspnet-api:
|
|
build:
|
|
context: ./backend/aspnet
|
|
dockerfile: Dockerfile.dev
|
|
ports:
|
|
- "5001:80"
|
|
environment:
|
|
- ASPNETCORE_ENVIRONMENT=Development
|
|
- ConnectionStrings__DefaultConnection={{DEV_DATABASE_URL}}
|
|
- Redis__ConnectionString={{DEV_REDIS_URL}}
|
|
volumes:
|
|
- ./backend/aspnet:/app
|
|
|
|
postgres:
|
|
image: postgres:15
|
|
ports:
|
|
- "5432:5432"
|
|
environment:
|
|
- POSTGRES_DB={{DEV_DB_NAME}}
|
|
- POSTGRES_USER={{DEV_DB_USER}}
|
|
- POSTGRES_PASSWORD={{DEV_DB_PASSWORD}}
|
|
volumes:
|
|
- postgres_data:/var/lib/postgresql/data
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
ports:
|
|
- "6379:6379"
|
|
|
|
volumes:
|
|
postgres_data:
|
|
```
|
|
|
|
### Production Environment
|
|
\```yaml
|
|
# docker-compose.prod.yml
|
|
version: '3.8'
|
|
services:
|
|
frontend:
|
|
build:
|
|
context: ./frontend
|
|
dockerfile: Dockerfile.prod
|
|
ports:
|
|
- "80:80"
|
|
environment:
|
|
- NODE_ENV=production
|
|
- REACT_APP_API_URL={{PROD_API_URL}}
|
|
|
|
nodejs-api:
|
|
build:
|
|
context: ./backend/nodejs
|
|
dockerfile: Dockerfile.prod
|
|
ports:
|
|
- "5000:5000"
|
|
environment:
|
|
- NODE_ENV=production
|
|
- DATABASE_URL={{PROD_DATABASE_URL}}
|
|
- REDIS_URL={{PROD_REDIS_URL}}
|
|
deploy:
|
|
replicas: 2
|
|
resources:
|
|
limits:
|
|
memory: 512M
|
|
reservations:
|
|
memory: 256M
|
|
|
|
aspnet-api:
|
|
build:
|
|
context: ./backend/aspnet
|
|
dockerfile: Dockerfile.prod
|
|
ports:
|
|
- "5001:80"
|
|
environment:
|
|
- ASPNETCORE_ENVIRONMENT=Production
|
|
- ConnectionStrings__DefaultConnection={{PROD_DATABASE_URL}}
|
|
- Redis__ConnectionString={{PROD_REDIS_URL}}
|
|
deploy:
|
|
replicas: 2
|
|
resources:
|
|
limits:
|
|
memory: 512M
|
|
reservations:
|
|
memory: 256M
|
|
```
|
|
|
|
## Containerization
|
|
|
|
### Frontend Dockerfile (React)
|
|
\```dockerfile
|
|
# Dockerfile.prod for React frontend
|
|
FROM node:18-alpine as build
|
|
|
|
WORKDIR /app
|
|
COPY package*.json ./
|
|
RUN npm ci --only=production
|
|
|
|
COPY . .
|
|
RUN npm run build
|
|
|
|
FROM nginx:alpine
|
|
COPY --from=build /app/build /usr/share/nginx/html
|
|
COPY nginx.conf /etc/nginx/nginx.conf
|
|
|
|
EXPOSE 80
|
|
CMD ["nginx", "-g", "daemon off;"]
|
|
```
|
|
|
|
### Backend Dockerfile (Node.js)
|
|
\```dockerfile
|
|
# Dockerfile.prod for Node.js API
|
|
FROM node:18-alpine
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy package files
|
|
COPY package*.json ./
|
|
RUN npm ci --only=production
|
|
|
|
# Copy source code
|
|
COPY . .
|
|
|
|
# Create non-root user
|
|
RUN addgroup -g 1001 -S nodejs
|
|
RUN adduser -S nodejs -u 1001
|
|
USER nodejs
|
|
|
|
EXPOSE 5000
|
|
|
|
CMD ["node", "server.js"]
|
|
```
|
|
|
|
### Backend Dockerfile (ASP.NET)
|
|
\```dockerfile
|
|
# Dockerfile.prod for ASP.NET API
|
|
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
|
|
WORKDIR /app
|
|
EXPOSE 80
|
|
|
|
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
|
|
WORKDIR /src
|
|
COPY ["{{PROJECT_NAME}}.csproj", "."]
|
|
RUN dotnet restore "{{PROJECT_NAME}}.csproj"
|
|
COPY . .
|
|
WORKDIR "/src/."
|
|
RUN dotnet build "{{PROJECT_NAME}}.csproj" -c Release -o /app/build
|
|
|
|
FROM build AS publish
|
|
RUN dotnet publish "{{PROJECT_NAME}}.csproj" -c Release -o /app/publish
|
|
|
|
FROM base AS final
|
|
WORKDIR /app
|
|
COPY --from=publish /app/publish .
|
|
ENTRYPOINT ["dotnet", "{{PROJECT_NAME}}.dll"]
|
|
```
|
|
|
|
## Kubernetes Deployment
|
|
|
|
### Namespace Configuration
|
|
\```yaml
|
|
# namespace.yaml
|
|
apiVersion: v1
|
|
kind: Namespace
|
|
metadata:
|
|
name: {{PROJECT_NAME}}
|
|
labels:
|
|
name: {{PROJECT_NAME}}
|
|
```
|
|
|
|
### Frontend Deployment
|
|
\```yaml
|
|
# frontend-deployment.yaml
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: frontend
|
|
namespace: {{PROJECT_NAME}}
|
|
spec:
|
|
replicas: 2
|
|
selector:
|
|
matchLabels:
|
|
app: frontend
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: frontend
|
|
spec:
|
|
containers:
|
|
- name: frontend
|
|
image: {{CONTAINER_REGISTRY}}/{{PROJECT_NAME}}-frontend:{{VERSION}}
|
|
ports:
|
|
- containerPort: 80
|
|
env:
|
|
- name: REACT_APP_API_URL
|
|
value: "{{API_URL}}"
|
|
resources:
|
|
requests:
|
|
memory: "128Mi"
|
|
cpu: "100m"
|
|
limits:
|
|
memory: "256Mi"
|
|
cpu: "200m"
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: frontend-service
|
|
namespace: {{PROJECT_NAME}}
|
|
spec:
|
|
selector:
|
|
app: frontend
|
|
ports:
|
|
- port: 80
|
|
targetPort: 80
|
|
type: LoadBalancer
|
|
```
|
|
|
|
### Backend API Deployments
|
|
\```yaml
|
|
# nodejs-api-deployment.yaml
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: nodejs-api
|
|
namespace: {{PROJECT_NAME}}
|
|
spec:
|
|
replicas: 2
|
|
selector:
|
|
matchLabels:
|
|
app: nodejs-api
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: nodejs-api
|
|
spec:
|
|
containers:
|
|
- name: nodejs-api
|
|
image: {{CONTAINER_REGISTRY}}/{{PROJECT_NAME}}-nodejs-api:{{VERSION}}
|
|
ports:
|
|
- containerPort: 5000
|
|
env:
|
|
- name: NODE_ENV
|
|
value: "production"
|
|
- name: DATABASE_URL
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: database-secret
|
|
key: connection-string
|
|
- name: REDIS_URL
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: redis-secret
|
|
key: connection-string
|
|
resources:
|
|
requests:
|
|
memory: "256Mi"
|
|
cpu: "200m"
|
|
limits:
|
|
memory: "512Mi"
|
|
cpu: "500m"
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: nodejs-api-service
|
|
namespace: {{PROJECT_NAME}}
|
|
spec:
|
|
selector:
|
|
app: nodejs-api
|
|
ports:
|
|
- port: 5000
|
|
targetPort: 5000
|
|
```
|
|
|
|
### Database Configuration
|
|
\```yaml
|
|
# postgres-deployment.yaml
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: postgres
|
|
namespace: {{PROJECT_NAME}}
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: postgres
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: postgres
|
|
spec:
|
|
containers:
|
|
- name: postgres
|
|
image: postgres:15
|
|
ports:
|
|
- containerPort: 5432
|
|
env:
|
|
- name: POSTGRES_DB
|
|
value: "{{DATABASE_NAME}}"
|
|
- name: POSTGRES_USER
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: database-secret
|
|
key: username
|
|
- name: POSTGRES_PASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: database-secret
|
|
key: password
|
|
volumeMounts:
|
|
- name: postgres-storage
|
|
mountPath: /var/lib/postgresql/data
|
|
resources:
|
|
requests:
|
|
memory: "512Mi"
|
|
cpu: "300m"
|
|
limits:
|
|
memory: "1Gi"
|
|
cpu: "500m"
|
|
volumes:
|
|
- name: postgres-storage
|
|
persistentVolumeClaim:
|
|
claimName: postgres-pvc
|
|
---
|
|
apiVersion: v1
|
|
kind: Service
|
|
metadata:
|
|
name: postgres-service
|
|
namespace: {{PROJECT_NAME}}
|
|
spec:
|
|
selector:
|
|
app: postgres
|
|
ports:
|
|
- port: 5432
|
|
targetPort: 5432
|
|
```
|
|
|
|
## CI/CD Pipeline
|
|
|
|
### GitHub Actions Workflow
|
|
\```yaml
|
|
# .github/workflows/deploy.yml
|
|
name: Deploy to Production
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
jobs:
|
|
test:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Setup Node.js
|
|
uses: actions/setup-node@v3
|
|
with:
|
|
node-version: '18'
|
|
cache: 'npm'
|
|
|
|
- name: Install dependencies
|
|
run: npm ci
|
|
|
|
- name: Run tests
|
|
run: npm test
|
|
|
|
- name: Run linting
|
|
run: npm run lint
|
|
|
|
- name: Security audit
|
|
run: npm audit
|
|
|
|
build-and-push:
|
|
needs: test
|
|
runs-on: ubuntu-latest
|
|
if: github.ref == 'refs/heads/main'
|
|
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Login to Container Registry
|
|
uses: docker/login-action@v2
|
|
with:
|
|
registry: {{CONTAINER_REGISTRY}}
|
|
username: ${{ secrets.REGISTRY_USERNAME }}
|
|
password: ${{ secrets.REGISTRY_PASSWORD }}
|
|
|
|
- name: Build and push Frontend
|
|
uses: docker/build-push-action@v4
|
|
with:
|
|
context: ./frontend
|
|
file: ./frontend/Dockerfile.prod
|
|
push: true
|
|
tags: {{CONTAINER_REGISTRY}}/{{PROJECT_NAME}}-frontend:${{ github.sha }}
|
|
|
|
- name: Build and push Node.js API
|
|
uses: docker/build-push-action@v4
|
|
with:
|
|
context: ./backend/nodejs
|
|
file: ./backend/nodejs/Dockerfile.prod
|
|
push: true
|
|
tags: {{CONTAINER_REGISTRY}}/{{PROJECT_NAME}}-nodejs-api:${{ github.sha }}
|
|
|
|
- name: Build and push ASP.NET API
|
|
uses: docker/build-push-action@v4
|
|
with:
|
|
context: ./backend/aspnet
|
|
file: ./backend/aspnet/Dockerfile.prod
|
|
push: true
|
|
tags: {{CONTAINER_REGISTRY}}/{{PROJECT_NAME}}-aspnet-api:${{ github.sha }}
|
|
|
|
deploy:
|
|
needs: build-and-push
|
|
runs-on: ubuntu-latest
|
|
if: github.ref == 'refs/heads/main'
|
|
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Setup kubectl
|
|
uses: azure/setup-kubectl@v3
|
|
with:
|
|
version: 'latest'
|
|
|
|
- name: Set up Kubeconfig
|
|
run: |
|
|
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig
|
|
export KUBECONFIG=kubeconfig
|
|
|
|
- name: Deploy to Kubernetes
|
|
run: |
|
|
sed -i 's/{{VERSION}}/${{ github.sha }}/g' k8s/*.yaml
|
|
kubectl apply -f k8s/
|
|
kubectl rollout status deployment/frontend -n {{PROJECT_NAME}}
|
|
kubectl rollout status deployment/nodejs-api -n {{PROJECT_NAME}}
|
|
kubectl rollout status deployment/aspnet-api -n {{PROJECT_NAME}}
|
|
```
|
|
|
|
## Infrastructure as Code
|
|
|
|
### Terraform Configuration
|
|
```hcl
|
|
# main.tf
|
|
terraform {
|
|
required_providers {
|
|
azurerm = {
|
|
source = "hashicorp/azurerm"
|
|
version = "~>3.0"
|
|
}
|
|
}
|
|
}
|
|
|
|
provider "azurerm" {
|
|
features {}
|
|
}
|
|
|
|
resource "azurerm_resource_group" "main" {
|
|
name = "{{PROJECT_NAME}}-rg"
|
|
location = "{{AZURE_REGION}}"
|
|
}
|
|
|
|
resource "azurerm_kubernetes_cluster" "main" {
|
|
name = "{{PROJECT_NAME}}-aks"
|
|
location = azurerm_resource_group.main.location
|
|
resource_group_name = azurerm_resource_group.main.name
|
|
dns_prefix = "{{PROJECT_NAME}}-aks"
|
|
|
|
default_node_pool {
|
|
name = "default"
|
|
node_count = {{NODE_COUNT}}
|
|
vm_size = "{{VM_SIZE}}"
|
|
}
|
|
|
|
identity {
|
|
type = "SystemAssigned"
|
|
}
|
|
|
|
tags = {
|
|
Environment = "{{ENVIRONMENT}}"
|
|
Project = "{{PROJECT_NAME}}"
|
|
}
|
|
}
|
|
|
|
resource "azurerm_postgresql_server" "main" {
|
|
name = "{{PROJECT_NAME}}-postgres"
|
|
location = azurerm_resource_group.main.location
|
|
resource_group_name = azurerm_resource_group.main.name
|
|
|
|
administrator_login = "{{DB_ADMIN_USER}}"
|
|
administrator_login_password = "{{DB_ADMIN_PASSWORD}}"
|
|
|
|
sku_name = "{{POSTGRES_SKU}}"
|
|
version = "{{POSTGRES_VERSION}}"
|
|
storage_mb = {{POSTGRES_STORAGE_MB}}
|
|
|
|
backup_retention_days = {{BACKUP_RETENTION_DAYS}}
|
|
geo_redundant_backup_enabled = {{GEO_REDUNDANT_BACKUP}}
|
|
auto_grow_enabled = true
|
|
|
|
public_network_access_enabled = false
|
|
ssl_enforcement_enabled = true
|
|
ssl_minimal_tls_version_enforced = "TLS1_2"
|
|
}
|
|
|
|
resource "azurerm_redis_cache" "main" {
|
|
name = "{{PROJECT_NAME}}-redis"
|
|
location = azurerm_resource_group.main.location
|
|
resource_group_name = azurerm_resource_group.main.name
|
|
capacity = {{REDIS_CAPACITY}}
|
|
family = "{{REDIS_FAMILY}}"
|
|
sku_name = "{{REDIS_SKU}}"
|
|
enable_non_ssl_port = false
|
|
minimum_tls_version = "1.2"
|
|
|
|
redis_configuration {
|
|
enable_authentication = true
|
|
}
|
|
}
|
|
```
|
|
|
|
## Monitoring and Observability
|
|
|
|
### Application Insights Configuration
|
|
\```yaml
|
|
# monitoring-deployment.yaml
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: monitoring-agent
|
|
namespace: {{PROJECT_NAME}}
|
|
spec:
|
|
replicas: 1
|
|
selector:
|
|
matchLabels:
|
|
app: monitoring-agent
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: monitoring-agent
|
|
spec:
|
|
containers:
|
|
- name: prometheus
|
|
image: prom/prometheus:latest
|
|
ports:
|
|
- containerPort: 9090
|
|
volumeMounts:
|
|
- name: prometheus-config
|
|
mountPath: /etc/prometheus
|
|
- name: grafana
|
|
image: grafana/grafana:latest
|
|
ports:
|
|
- containerPort: 3000
|
|
env:
|
|
- name: GF_SECURITY_ADMIN_PASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: monitoring-secret
|
|
key: grafana-password
|
|
volumes:
|
|
- name: prometheus-config
|
|
configMap:
|
|
name: prometheus-config
|
|
```
|
|
|
|
### Logging Configuration
|
|
\```yaml
|
|
# logging-config.yaml
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: fluent-bit-config
|
|
namespace: {{PROJECT_NAME}}
|
|
data:
|
|
fluent-bit.conf: |
|
|
[SERVICE]
|
|
Flush 1
|
|
Log_Level info
|
|
Daemon off
|
|
Parsers_File parsers.conf
|
|
HTTP_Server On
|
|
HTTP_Listen 0.0.0.0
|
|
HTTP_Port 2020
|
|
|
|
[INPUT]
|
|
Name tail
|
|
Path /var/log/containers/*.log
|
|
Parser docker
|
|
Tag kube.*
|
|
Refresh_Interval 5
|
|
Mem_Buf_Limit 50MB
|
|
Skip_Long_Lines On
|
|
|
|
[FILTER]
|
|
Name kubernetes
|
|
Match kube.*
|
|
Kube_URL https://kubernetes.default.svc:443
|
|
Kube_CA_File /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
|
Kube_Token_File /var/run/secrets/kubernetes.io/serviceaccount/token
|
|
Kube_Tag_Prefix kube.var.log.containers.
|
|
Merge_Log On
|
|
Keep_Log Off
|
|
|
|
[OUTPUT]
|
|
Name azure
|
|
Match *
|
|
Customer_ID {{LOG_ANALYTICS_WORKSPACE_ID}}
|
|
Shared_Key {{LOG_ANALYTICS_SHARED_KEY}}
|
|
Log_Type {{PROJECT_NAME}}_logs
|
|
```
|
|
|
|
## Security Configuration
|
|
|
|
### Network Policies
|
|
\```yaml
|
|
# network-policy.yaml
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: NetworkPolicy
|
|
metadata:
|
|
name: {{PROJECT_NAME}}-network-policy
|
|
namespace: {{PROJECT_NAME}}
|
|
spec:
|
|
podSelector: {}
|
|
policyTypes:
|
|
- Ingress
|
|
- Egress
|
|
ingress:
|
|
- from:
|
|
- namespaceSelector:
|
|
matchLabels:
|
|
name: {{PROJECT_NAME}}
|
|
ports:
|
|
- protocol: TCP
|
|
port: 80
|
|
- protocol: TCP
|
|
port: 5000
|
|
- protocol: TCP
|
|
port: 5001
|
|
egress:
|
|
- to:
|
|
- namespaceSelector:
|
|
matchLabels:
|
|
name: {{PROJECT_NAME}}
|
|
ports:
|
|
- protocol: TCP
|
|
port: 5432
|
|
- protocol: TCP
|
|
port: 6379
|
|
- to: []
|
|
ports:
|
|
- protocol: TCP
|
|
port: 443
|
|
- protocol: TCP
|
|
port: 53
|
|
- protocol: UDP
|
|
port: 53
|
|
```
|
|
|
|
### Secret Management
|
|
\```yaml
|
|
# secrets.yaml
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: database-secret
|
|
namespace: {{PROJECT_NAME}}
|
|
type: Opaque
|
|
data:
|
|
connection-string: {{BASE64_ENCODED_DB_CONNECTION}}
|
|
username: {{BASE64_ENCODED_DB_USERNAME}}
|
|
password: {{BASE64_ENCODED_DB_PASSWORD}}
|
|
---
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: redis-secret
|
|
namespace: {{PROJECT_NAME}}
|
|
type: Opaque
|
|
data:
|
|
connection-string: {{BASE64_ENCODED_REDIS_CONNECTION}}
|
|
---
|
|
apiVersion: v1
|
|
kind: Secret
|
|
metadata:
|
|
name: api-keys
|
|
namespace: {{PROJECT_NAME}}
|
|
type: Opaque
|
|
data:
|
|
jwt-secret: {{BASE64_ENCODED_JWT_SECRET}}
|
|
api-key: {{BASE64_ENCODED_API_KEY}}
|
|
```
|
|
|
|
## Backup and Disaster Recovery
|
|
|
|
### Database Backup Strategy
|
|
\```bash
|
|
#!/bin/bash
|
|
# backup-database.sh
|
|
|
|
# Configuration
|
|
BACKUP_DIR="/backups"
|
|
DB_HOST="{{DATABASE_HOST}}"
|
|
DB_NAME="{{DATABASE_NAME}}"
|
|
DB_USER="{{DATABASE_USER}}"
|
|
RETENTION_DAYS=30
|
|
|
|
# Create backup directory
|
|
mkdir -p $BACKUP_DIR
|
|
|
|
# Generate backup filename with timestamp
|
|
BACKUP_FILE="$BACKUP_DIR/${DB_NAME}_$(date +%Y%m%d_%H%M%S).sql"
|
|
|
|
# Create database backup
|
|
pg_dump -h $DB_HOST -U $DB_USER -d $DB_NAME > $BACKUP_FILE
|
|
|
|
# Compress backup
|
|
gzip $BACKUP_FILE
|
|
|
|
# Upload to cloud storage
|
|
az storage blob upload \
|
|
--account-name {{STORAGE_ACCOUNT}} \
|
|
--container-name backups \
|
|
--name "database/$(basename $BACKUP_FILE.gz)" \
|
|
--file "$BACKUP_FILE.gz"
|
|
|
|
# Clean up old local backups
|
|
find $BACKUP_DIR -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
|
|
|
|
echo "Backup completed: $BACKUP_FILE.gz"
|
|
```
|
|
|
|
### Disaster Recovery Plan
|
|
1. **RTO (Recovery Time Objective):** {{RTO_TARGET}}
|
|
2. **RPO (Recovery Point Objective):** {{RPO_TARGET}}
|
|
3. **Backup Frequency:** {{BACKUP_FREQUENCY}}
|
|
4. **Recovery Procedures:** {{RECOVERY_PROCEDURES}}
|
|
|
|
## Performance Optimization
|
|
|
|
### Resource Limits and Requests
|
|
\```yaml
|
|
# resource-optimization.yaml
|
|
apiVersion: v1
|
|
kind: LimitRange
|
|
metadata:
|
|
name: {{PROJECT_NAME}}-limits
|
|
namespace: {{PROJECT_NAME}}
|
|
spec:
|
|
limits:
|
|
- default:
|
|
memory: "512Mi"
|
|
cpu: "500m"
|
|
defaultRequest:
|
|
memory: "256Mi"
|
|
cpu: "200m"
|
|
type: Container
|
|
```
|
|
|
|
### Horizontal Pod Autoscaler
|
|
\```yaml
|
|
# hpa.yaml
|
|
apiVersion: autoscaling/v2
|
|
kind: HorizontalPodAutoscaler
|
|
metadata:
|
|
name: frontend-hpa
|
|
namespace: {{PROJECT_NAME}}
|
|
spec:
|
|
scaleTargetRef:
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
name: frontend
|
|
minReplicas: 2
|
|
maxReplicas: 10
|
|
metrics:
|
|
- type: Resource
|
|
resource:
|
|
name: cpu
|
|
target:
|
|
type: Utilization
|
|
averageUtilization: 70
|
|
- type: Resource
|
|
resource:
|
|
name: memory
|
|
target:
|
|
type: Utilization
|
|
averageUtilization: 80
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues and Solutions
|
|
|
|
#### Issue: Pod Startup Failures
|
|
**Symptoms:** Pods stuck in `CrashLoopBackOff` or `ImagePullBackOff`
|
|
**Solutions:**
|
|
1. Check image availability: `kubectl describe pod <pod-name>`
|
|
2. Verify resource limits: `kubectl get events`
|
|
3. Check logs: `kubectl logs <pod-name>`
|
|
|
|
#### Issue: Database Connection Failures
|
|
**Symptoms:** API services unable to connect to database
|
|
**Solutions:**
|
|
1. Verify database service: `kubectl get svc postgres-service`
|
|
2. Check network policies: `kubectl get networkpolicy`
|
|
3. Validate secrets: `kubectl get secret database-secret -o yaml`
|
|
|
|
#### Issue: High Memory Usage
|
|
**Symptoms:** Pods being killed due to OOMKilled
|
|
**Solutions:**
|
|
1. Increase memory limits in deployment
|
|
2. Optimize application memory usage
|
|
3. Implement memory profiling
|
|
|
|
### Debugging Commands
|
|
\```bash
|
|
# Check pod status
|
|
kubectl get pods -n {{PROJECT_NAME}}
|
|
|
|
# View pod logs
|
|
kubectl logs -f <pod-name> -n {{PROJECT_NAME}}
|
|
|
|
# Describe pod for events
|
|
kubectl describe pod <pod-name> -n {{PROJECT_NAME}}
|
|
|
|
# Execute into pod for debugging
|
|
kubectl exec -it <pod-name> -n {{PROJECT_NAME}} -- /bin/bash
|
|
|
|
# Check resource usage
|
|
kubectl top pods -n {{PROJECT_NAME}}
|
|
|
|
# View service endpoints
|
|
kubectl get endpoints -n {{PROJECT_NAME}}
|
|
```
|
|
|
|
## Rollback Procedures
|
|
|
|
### Automated Rollback
|
|
\```bash
|
|
#!/bin/bash
|
|
# rollback.sh
|
|
|
|
NAMESPACE="{{PROJECT_NAME}}"
|
|
DEPLOYMENT_NAME="$1"
|
|
REVISION="$2"
|
|
|
|
if [ -z "$DEPLOYMENT_NAME" ] || [ -z "$REVISION" ]; then
|
|
echo "Usage: $0 <deployment-name> <revision>"
|
|
exit 1
|
|
fi
|
|
|
|
echo "Rolling back $DEPLOYMENT_NAME to revision $REVISION..."
|
|
|
|
kubectl rollout undo deployment/$DEPLOYMENT_NAME --to-revision=$REVISION -n $NAMESPACE
|
|
|
|
echo "Waiting for rollback to complete..."
|
|
kubectl rollout status deployment/$DEPLOYMENT_NAME -n $NAMESPACE
|
|
|
|
echo "Rollback completed successfully"
|
|
```
|
|
|
|
### Manual Rollback Steps
|
|
1. **Identify target revision:** `kubectl rollout history deployment/<name>`
|
|
2. **Execute rollback:** `kubectl rollout undo deployment/<name> --to-revision=<number>`
|
|
3. **Verify rollback:** `kubectl rollout status deployment/<name>`
|
|
4. **Validate functionality:** Run health checks and integration tests
|
|
|
|
## Maintenance Procedures
|
|
|
|
### Regular Maintenance Tasks
|
|
1. **Weekly:**
|
|
- Review resource usage and scaling metrics
|
|
- Check backup integrity
|
|
- Update security patches
|
|
|
|
2. **Monthly:**
|
|
- Review and rotate secrets
|
|
- Analyze performance metrics
|
|
- Update dependencies
|
|
|
|
3. **Quarterly:**
|
|
- Disaster recovery testing
|
|
- Security audit
|
|
- Capacity planning review
|
|
|
|
### Maintenance Windows
|
|
- **Scheduled Maintenance:** {{MAINTENANCE_SCHEDULE}}
|
|
- **Emergency Maintenance:** {{EMERGENCY_PROCEDURES}}
|
|
- **Communication Plan:** {{MAINTENANCE_COMMUNICATION}}
|
|
|
|
---
|
|
|
|
## Template Usage Notes
|
|
|
|
### Variable Substitution Guide
|
|
Replace all `{{VARIABLE_NAME}}` placeholders with environment-specific information.
|
|
|
|
### Customization Options
|
|
- Adapt cloud provider configurations (Azure/AWS/GCP)
|
|
- Modify container orchestration platform (Kubernetes/Docker Swarm)
|
|
- Customize monitoring and logging solutions
|
|
- Adjust security policies based on compliance requirements
|
|
|
|
### Quality Validation Checklist
|
|
- [ ] All deployment configurations are tested
|
|
- [ ] Security policies are implemented and validated
|
|
- [ ] Monitoring and alerting are configured
|
|
- [ ] Backup and disaster recovery procedures are tested
|
|
- [ ] Performance optimization is implemented
|
|
- [ ] Troubleshooting procedures are documented
|
|
- [ ] Rollback procedures are tested and validated
|
|
|
|
### Integration Points
|
|
- **BMAD Personas:** DevOps Documentation Specialist, Cross-Platform Integration Specialist
|
|
- **Follow-up Templates:** Monitoring Template, Security Template
|
|
- **Quality Standards:** BMAD Method deployment quality framework
|
|
|
|
---
|
|
**Template Version:** 1.0.0
|
|
**Last Updated:** {{CURRENT_DATE}}
|
|
**Template Owner:** BMAD Method Team
|