1.kubernetes
Secret Management

Sensitive data flow

  • ✅ Sensitive values come from AWS Secrets Manager
  • ✅ Non-sensitive app configs come from Kubernetes ConfigMap
  • ✅ Jenkins pipeline auto-syncs secrets before deploy

🧱 1. AWS Secrets Manager Setup (Sanitized)

Run once to store sensitive values:

cat > secrets.json <<EOF
{
  "DB_USERNAME": "example_user",
  "DB_PASSWORD": "example_pass",
  "API_KEY": "example_api_key",
  "JWT_SECRET": "example_jwt_secret"
}
EOF
 
aws secretsmanager create-secret \
  --name {{SECRET_NAME}} \
  --secret-string file://secrets.json \
  --region {{AWS_REGION}}

🧩 2. Create ConfigMap (Non-Sensitive Vars)

File: manifest/configmap.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: {{APP_CONFIGMAP_NAME}}
data:
  NODE_ENV: "uat"
  PORT: "443"
  LOG_LEVEL: "info"
  BASE_URL: "https://{{SERVICE_DOMAIN_UAT}}"
  FEATURE_TOGGLE_XYZ: "true"

Apply:

kubectl apply -f manifest/configmap.yaml

🧠 3. Deployment Manifest (Sanitized)

File: manifest/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{APP_DEPLOYMENT_NAME}}
spec:
  replicas: 1
  selector:
    matchLabels:
      app: {{APP_DEPLOYMENT_NAME}}
  template:
    metadata:
      labels:
        app: {{APP_DEPLOYMENT_NAME}}
    spec:
      containers:
      - name: {{APP_DEPLOYMENT_NAME}}
        image: {{ECR_REPO_URL}}:latest
        ports:
        - containerPort: 443
        envFrom:
        - configMapRef:
            name: {{APP_CONFIGMAP_NAME}}
        - secretRef:
            name: {{APP_SECRET_NAME}}

⚙️ 4. Jenkinsfile — Fully Sanitized CI/CD

pipeline {
  agent any
 
  environment {
    registry       = '{{ECR_REPO_URL}}'
    aws_region     = '{{AWS_REGION}}'
    eks_cluster    = '{{EKS_CLUSTER_NAME}}'
    secret_name    = '{{SECRET_NAME}}'
    aws_credentials = '{{JENKINS_AWS_CREDENTIALS_ID}}'
  }
 
  stages {
 
    stage('Cleanup Old Build') {
      steps {
        sh 'docker system prune -f || true'
      }
    }
 
    stage('Docker Build & Push') {
      steps {
        sh '''
          docker build -t $registry:latest .
          aws ecr get-login-password --region $aws_region \
            | docker login --username AWS --password-stdin $registry
          docker push $registry:latest
        '''
      }
    }
 
    stage('Fetch Secrets from AWS Secrets Manager') {
      steps {
        withAWS(credentials: aws_credentials, region: "${aws_region}") {
          sh '''
            aws secretsmanager get-secret-value \
              --secret-id $secret_name \
              --region $aws_region \
              --query SecretString \
              --output text > secrets.json
 
            jq -r 'to_entries|map("\\(.key)=\\(.value)")|.[]' secrets.json > .env.k8s
 
            kubectl create secret generic {{APP_SECRET_NAME}} \
              --from-env-file=.env.k8s \
              --dry-run=client -o yaml | kubectl apply -f -
          '''
        }
      }
    }
 
    stage('Deploy to EKS') {
      steps {
        withAWS(credentials: aws_credentials, region: "${aws_region}") {
          sh '''
            aws eks update-kubeconfig \
              --region $aws_region --name $eks_cluster
 
            kubectl apply -f manifest/configmap.yaml
            kubectl apply -f manifest/deployment.yaml
            kubectl apply -f manifest/service.yaml
            kubectl apply -f manifest/hpa.yaml
            kubectl apply -f manifest/ingress.yaml
 
            kubectl rollout status deployment/{{APP_DEPLOYMENT_NAME}}
          '''
        }
      }
    }
  }
 
  post {
    always {
      cleanWs()
    }
  }
}

🔐 5. Secret Update Flow (Sanitized)

When secrets change:

  1. Update {{SECRET_NAME}} in AWS Secrets Manager.

  2. Jenkins pipeline will automatically:

    • fetch updated secrets
    • generate .env.k8s
    • apply updated K8s Secret
  3. Deployment uses new values instantly.


🧭 7. Final Architecture (Sanitized)

TypeSourceManaged ByUpdates
SensitiveAWS Secrets Manager → K8s SecretDevOpsOccasional
Non-sensitiveGit ConfigMap YAMLDevelopersFrequent