CI/CD DevOps Planning & Implementation

 

Cloud Web Application CI/CD DevOps Planning & Implementation on Kubernetes

This document outlines the planning and implementation steps for establishing a robust Continuous Integration (CI) and Continuous Delivery/Deployment (CD) pipeline for cloud-native web applications leveraging Kubernetes. We will cover two major cloud providers: Azure Kubernetes Service (AKS) and Amazon Elastic Kubernetes Service (EKS).

Executive Summary

Continuous Integration and Continuous Delivery (CI/CD) are fundamental practices in DevOps that automate the software delivery process. For cloud-native web applications deployed on Kubernetes, CI/CD streamlines code changes from development to production, ensuring rapid, reliable, and frequent releases. This document provides a blueprint for planning and implementing such pipelines on Azure and AWS, focusing on their respective Kubernetes services.

Section 1: Azure Kubernetes Service (AKS) CI/CD with Azure DevOps

This section details the planning and implementation of a CI/CD pipeline for a web application deployed on Azure Kubernetes Service (AKS) using Azure DevOps.

1.1 Overview of CI/CD for Web Apps on AKS

Azure Kubernetes Service (AKS) is a managed Kubernetes offering that simplifies deploying, managing, and scaling containerized applications in Azure. Azure DevOps provides a comprehensive set of development services, including Azure Repos (for Git version control), Azure Pipelines (for CI/CD), Azure Boards (for agile planning), and Azure Artifacts (for package management). This combination creates a powerful ecosystem for MLOps and web application delivery.

The CI/CD pipeline will automate the following:

  • Continuous Integration (CI):

    • Code commit to Azure Repos (Git).

    • Automated build of the web application.

    • Execution of unit and integration tests.

    • Creation of a Docker image for the web application.

    • Pushing the Docker image to Azure Container Registry (ACR).

  • Continuous Delivery/Deployment (CD):

    • Automatic triggering of deployment upon successful CI.

    • Deployment of Kubernetes manifests (or Helm charts) to AKS.

    • Updates to the running web application pods.

    • Rollback capabilities in case of deployment failures.

1.2 Planning Phase (Azure)

1.2.1 Requirements Gathering

  • Application Type: Single-page application (SPA), microservices, monolithic web app.

  • Language/Framework: Node.js, .NET, Python, Java, etc.

  • Testing Strategy: Unit, integration, end-to-end (E2E) tests.

  • Deployment Strategy: Rolling updates (default), Blue/Green, Canary releases.

  • Environment Strategy: Dev, Test/Staging, Production environments.

  • Security Requirements: Image scanning, secret management, RBAC for Kubernetes.

  • Monitoring & Logging: Desired tools and metrics.

  • Compliance: Any regulatory requirements for the pipeline and deployment.

1.2.2 Tooling Selection (Azure Specific)

  • Source Code Management (SCM): Azure Repos (Git) or GitHub.

  • CI/CD Orchestration: Azure Pipelines (YAML-based pipelines).

  • Container Registry: Azure Container Registry (ACR).

  • Kubernetes Cluster: Azure Kubernetes Service (AKS).

  • Secret Management: Azure Key Vault for application secrets, Azure DevOps Variable Groups for pipeline secrets.

  • Configuration Management: Kubernetes ConfigMaps/Secrets, Helm charts.

  • Monitoring & Logging: Azure Monitor, Azure Log Analytics, Application Insights.

  • Infrastructure as Code (IaC): Azure Resource Manager (ARM) templates or Bicep for provisioning Azure resources (ACR, AKS, VNet, etc.).

1.2.3 Architecture Design

  • Application Architecture: Define microservices (if applicable), APIs, frontend components.

  • Network Topology: Design Azure VNet, subnets for AKS, Private Link for secure access to ACR/Key Vault.

  • Kubernetes Configuration: Define namespaces for environments, resource quotas, network policies.

  • Service Exposure: Use Azure Load Balancer or Azure Application Gateway (with Ingress Controller) for exposing web applications.

1.3 Implementation Phase (Azure) - Step-by-Step

1.3.1 Step 1: Azure Resource Provisioning (IaC)

  1. Create an Azure Resource Group: A logical container for all your Azure resources.

    az group create --name MyWebAppRG --location eastus
    
  2. Create Azure Container Registry (ACR): To store your Docker images.

    az acr create --resource-group MyWebAppRG --name mywebappacr --sku Standard
    
  3. Create Azure Kubernetes Service (AKS) Cluster:

    az aks create \
      --resource-group MyWebAppRG \
      --name mywebappaks \
      --node-count 3 \
      --generate-ssh-keys \
      --attach-acr mywebappacr \
      --enable-managed-identity # Recommended for secure access
    

    This command also attaches ACR to AKS, enabling authenticated image pulls.

  4. Configure kubectl to connect to your AKS cluster:

    az aks get-credentials --resource-group MyWebAppRG --name mywebappaks --overwrite-existing
    
  5. (Optional but Recommended) Azure Key Vault: Create an Azure Key Vault for storing application secrets and integrate it with AKS using CSI Driver.

    az keyvault create --name mywebappkv --resource-group MyWebAppRG --location eastus
    

1.3.2 Step 2: Source Code Management

  1. Initialize Git Repository: Create a new Git repository in Azure Repos or GitHub.

  2. Commit Application Code: Place your web application code, Dockerfile, and Kubernetes manifest files (e.g., deployment.yaml, service.yaml, ingress.yaml) into the repository.

    • Example Dockerfile (for a Node.js app):

      # Use an official Node.js runtime as a parent image
      FROM node:18-alpine
      
      # Set the working directory in the container
      WORKDIR /app
      
      # Copy package.json and package-lock.json to the working directory
      COPY package*.json ./
      
      # Install dependencies
      RUN npm install
      
      # Copy the rest of the application code
      COPY . .
      
      # Expose the port the app runs on
      EXPOSE 8080
      
      # Define the command to run the app
      CMD [ "npm", "start" ]
      
    • Example deployment.yaml:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: mywebapp-deployment
        labels:
          app: mywebapp
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: mywebapp
        template:
          metadata:
            labels:
              app: mywebapp
          spec:
            containers:
            - name: mywebapp
              image: mywebappacr.azurecr.io/mywebapp:$(Build.BuildId) # Image will be replaced by pipeline
              ports:
              - containerPort: 8080
              env: # Example for injecting secrets from Key Vault via CSI Driver
                - name: MY_APP_SECRET
                  valueFrom:
                    secretKeyRef:
                      name: my-kv-secrets
                      key: my-secret-key
            imagePullSecrets: # Required for pulling from private ACR
            - name: acr-secret # This secret is typically managed by AKS integration with ACR
      

1.3.3 Step 3: Configure Azure Pipelines (CI)

  1. Create a New Pipeline: In Azure DevOps, navigate to Pipelines -> Pipelines and click New pipeline.

  2. Select Source: Choose your repository (Azure Repos Git or GitHub).

  3. Configure Pipeline:

    • Select the Docker template if you have a Dockerfile and want to build/push an image.

    • Alternatively, choose Starter pipeline for a custom YAML.

  4. Edit azure-pipelines.yml:

    • Trigger: Set up a trigger to start the CI pipeline on code commits to specific branches (e.g., main or master).

    • Build Stage:

      • Define tasks to build your application (e.g., npm install, npm build).

      • Run unit/integration tests.

      • Build the Docker image: Use the Docker@2 task to build your image.

      • Push the Docker image to ACR: Use the Docker@2 task with command: push to push the image to mywebappacr.azurecr.io/mywebapp. Tag the image with $(Build.BuildId) or a specific version.

      • (Security Best Practice): Integrate container image scanning (e.g., Azure Security Center, Trivy, Snyk) as part of the build stage to detect vulnerabilities before pushing.

    Example CI Stage (snippet in azure-pipelines.yml):

    # azure-pipelines.yml
    trigger:
    - main
    
    variables:
      # Agent VM image name
      vmImageName: 'ubuntu-latest'
      # Container registry service connection established during pipeline creation
      dockerRegistryServiceConnection: 'your-acr-service-connection' # Auto-generated by Azure DevOps
      imageRepository: 'mywebapp'
      dockerfilePath: '$(Build.SourcesDirectory)/Dockerfile'
      tag: '$(Build.BuildId)'
    
    stages:
    - stage: Build
      displayName: Build and push stage
      jobs:
      - job: BuildAndPush
        displayName: Build and Push
        pool:
          vmImage: $(vmImageName)
        steps:
        - task: Docker@2
          displayName: Build and push an image to ACR
          inputs:
            containerRegistry: $(dockerRegistryServiceConnection)
            repository: $(imageRepository)
            command: 'buildAndPush'
            Dockerfile: $(dockerfilePath)
            tags: |
              $(tag)
    

1.3.4 Step 4: Configure Azure Pipelines (CD)

  1. Create a Release Pipeline: In Azure DevOps, go to Pipelines -> Releases and click New pipeline.

  2. Select Artifact: Link your CI build pipeline as an artifact source. Enable continuous deployment trigger.

  3. Define Stages (Environments): Create stages for Dev, Staging, Production.

    • For each stage, add an Agent job.

    • Kubernetes Service Connection: Create a Kubernetes service connection in Azure DevOps for your AKS cluster (Project settings -> Service connections).

    • Deployment Task:

      • Use the KubernetesManifest@1 task or the HelmDeploy@0 task (if using Helm charts).

      • Specify the Kubernetes service connection, namespace, and manifest files (deployment.yaml, service.yaml, ingress.yaml).

      • Replace image placeholders in your manifest ($(Build.BuildId)) with the actual image tag from the CI artifact.

      • (Deployment Strategy): Implement rolling updates by default. For advanced strategies (Blue/Green, Canary), use a service mesh (e.g., Istio) or specialized tools like Azure Deployment Manager combined with pipeline logic.

      • (Rollback Strategy): Plan for rollbacks by ensuring previous stable images are available and having pipeline steps to revert deployments.

    Example CD Stage (snippet in azure-pipelines.yml or separate release pipeline): (Often, for Kubernetes deployments, the CD part is also defined in the same azure-pipelines.yml using stages)

    # ... (previous build stage) ...
    
    - stage: Deploy
      displayName: Deploy to AKS
      dependsOn: Build # Depends on the successful completion of the Build stage
      condition: succeeded()
      jobs:
      - deployment: DeployWebApp
        displayName: Deploy Web App
        environment: 'dev.default' # Define an environment in Azure DevOps for better governance
        pool:
          vmImage: $(vmImageName)
        variables:
          kubernetesServiceConnection: 'your-aks-service-connection' # Service connection created in Azure DevOps
          namespace: 'default' # or 'dev', 'staging', 'prod'
          imageNameWithTag: '$(imageRepository):$(tag)'
        strategy:
          runOnce:
            deploy:
              steps:
              - task: KubernetesManifest@1
                displayName: Deploy to Kubernetes cluster
                inputs:
                  action: deploy
                  kubernetesServiceConnection: $(kubernetesServiceConnection)
                  namespace: $(namespace)
                  manifests: |
                    $(Build.SourcesDirectory)/kubernetes/deployment.yaml
                    $(Build.SourcesDirectory)/kubernetes/service.yaml
                  containers: |
                    $(ACR_LOGIN_SERVER)/$(imageNameWithTag) # ACR_LOGIN_SERVER is a predefined variable
              - task: Kubernetes@1 # Optional: Verify deployment
                displayName: Verify Deployment
                inputs:
                  command: 'get'
                  arguments: 'pods -n $(namespace) -l app=mywebapp'
                  kubernetesServiceConnection: $(kubernetesServiceConnection)
    

1.3.5 Step 5: Monitoring, Logging, and Security Integration

  1. Azure Monitor & Log Analytics: Enable container insights for your AKS cluster (az aks enable-addons --addons monitoring --name mywebappaks --resource-group MyWebAppRG) to collect pod, node, and container logs/metrics.

  2. Application Insights: Instrument your web application with Application Insights SDK for application-level monitoring (performance, errors, user behavior).

  3. Azure Security Center / Microsoft Defender for Cloud: Monitor your AKS cluster and ACR for security posture, vulnerabilities, and threats.

  4. Azure Policy: Apply Azure Policies to enforce security standards on your AKS cluster (e.g., disallow privileged containers).

  5. Role-Based Access Control (RBAC): Ensure proper RBAC is configured within AKS for service accounts used by deployments, and limit permissions of Azure DevOps service connections.

Section 2: AWS Elastic Kubernetes Service (EKS) CI/CD with AWS DevOps Tools

This section outlines the planning and implementation of a CI/CD pipeline for a web application deployed on Amazon Elastic Kubernetes Service (EKS) using AWS DevOps services.

2.1 Overview of CI/CD for Web Apps on EKS

Amazon Elastic Kubernetes Service (EKS) is a managed Kubernetes service that makes it easy to run Kubernetes on AWS without needing to install, operate, and maintain your own Kubernetes control plane. AWS DevOps services like AWS CodeCommit (for Git), AWS CodeBuild (for CI), AWS CodePipeline (for CD orchestration), and Amazon Elastic Container Registry (ECR) provide a robust, integrated suite for automating software delivery on EKS.

The CI/CD pipeline will automate the following:

  • Continuous Integration (CI):

    • Code commit to AWS CodeCommit (or GitHub).

    • Automated build of the web application.

    • Execution of unit and integration tests.

    • Creation of a Docker image for the web application.

    • Pushing the Docker image to Amazon Elastic Container Registry (ECR).

  • Continuous Delivery/Deployment (CD):

    • Automatic triggering of deployment upon successful CI.

    • Deployment of Kubernetes manifests (or Helm charts) to EKS.

    • Updates to the running web application pods.

    • Rollback capabilities in case of deployment failures.

2.2 Planning Phase (AWS)

2.2.1 Requirements Gathering

  • Application Type: Single-page application (SPA), microservices, monolithic web app.

  • Language/Framework: Node.js, .NET, Python, Java, etc.

  • Testing Strategy: Unit, integration, end-to-end (E2E) tests.

  • Deployment Strategy: Rolling updates (default), Blue/Green, Canary releases.

  • Environment Strategy: Dev, Test/Staging, Production environments.

  • Security Requirements: Image scanning, secret management, RBAC for Kubernetes.

  • Monitoring & Logging: Desired tools and metrics.

  • Compliance: Any regulatory requirements for the pipeline and deployment.

2.2.2 Tooling Selection (AWS Specific)

  • Source Code Management (SCM): AWS CodeCommit or GitHub.

  • CI/CD Orchestration: AWS CodePipeline.

  • Build Service: AWS CodeBuild.

  • Container Registry: Amazon Elastic Container Registry (ECR).

  • Kubernetes Cluster: Amazon Elastic Kubernetes Service (EKS).

  • Secret Management: AWS Secrets Manager for application secrets, AWS Systems Manager Parameter Store for configuration parameters.

  • Configuration Management: Kubernetes ConfigMaps/Secrets, Helm charts.

  • Monitoring & Logging: Amazon CloudWatch, AWS CloudTrail, Amazon CloudWatch Container Insights.

  • Infrastructure as Code (IaC): AWS CloudFormation or Terraform for provisioning AWS resources (ECR, EKS, VPC, etc.).

2.2.3 Architecture Design

  • Application Architecture: Define microservices (if applicable), APIs, frontend components.

  • Network Topology: Design AWS VPC, subnets for EKS (public/private), security groups, NAT Gateways for private EKS access.

  • Kubernetes Configuration: Define namespaces for environments, resource quotas, network policies.

  • Service Exposure: Use AWS Application Load Balancer (ALB) or Network Load Balancer (NLB) with Kubernetes Ingress Controller for exposing web applications.

2.3 Implementation Phase (AWS) - Step-by-Step

2.3.1 Step 1: AWS Resource Provisioning (IaC)

  1. Create AWS VPC and Subnets: Crucial for EKS networking.

    # Using eksctl for simpler VPC/EKS creation (recommended for quick setup)
    eksctl create cluster --name mywebappeks --version 1.28 --region us-east-1 --nodegroup-name mywebapp-nodes --node-type t3.medium --nodes 3 --zones us-east-1a,us-east-1b
    

    This command will create a VPC, subnets, and an EKS cluster.

  2. Create Amazon Elastic Container Registry (ECR) Repository: To store your Docker images.

    aws ecr create-repository --repository-name mywebapp --region us-east-1
    
  3. Configure kubectl to connect to your EKS cluster:

    aws eks update-kubeconfig --name mywebappeks --region us-east-1
    
  4. (Optional but Recommended) AWS Secrets Manager: Create secrets for your application.

    aws secretsmanager create-secret --name /mywebapp/secrets/api_key --secret-string "my_super_secret_value" --region us-east-1
    

2.3.2 Step 2: Source Code Management

  1. Initialize Git Repository: Create a new Git repository in AWS CodeCommit or GitHub.

  2. Commit Application Code: Place your web application code, Dockerfile, and Kubernetes manifest files (e.g., deployment.yaml, service.yaml, ingress.yaml) into the repository.

    • Example Dockerfile (for a Node.js app): (Same as Azure example)

    • Example deployment.yaml:

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: mywebapp-deployment
        labels:
          app: mywebapp
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: mywebapp
        template:
          metadata:
            labels:
              app: mywebapp
          spec:
            containers:
            - name: mywebapp
              image: <AWS_ACCOUNT_ID>.dkr.ecr.us-east-1.amazonaws.com/mywebapp:latest # Image will be replaced by CodeBuild
              ports:
              - containerPort: 8080
              env: # Example for injecting secrets from Secrets Manager via External Secrets Operator
                - name: MY_APP_SECRET
                  valueFrom:
                    secretKeyRef:
                      name: /mywebapp/secrets/api_key
                      key: my_secret_key
            # If using private ECR, ensure EKS Node IAM role has ECR pull permissions.
            # Kubernetes ImagePullSecrets are usually not needed if EKS node role has permissions.
      
    • Note: For injecting secrets from AWS Secrets Manager into Kubernetes, you'd typically use an External Secrets Operator or similar solution running within your EKS cluster.

2.3.3 Step 3: Configure AWS CodePipeline (CI/CD)

AWS CodePipeline orchestrates the entire CI/CD workflow. You define stages and actions within a pipeline.

  1. Create a New Pipeline: In the AWS CodePipeline console, click Create pipeline.

  2. Choose Pipeline Settings:

    • Provide a pipeline name.

    • Select New service role or an existing one.

  3. Source Stage:

    • Source Provider: Choose AWS CodeCommit or GitHub.

    • Select your repository and branch.

    • Choose Start the pipeline on every change for continuous integration.

    • Output Artifact Format: Select CodePipeline default.

  4. Build Stage (AWS CodeBuild):

    • Build Provider: Choose AWS CodeBuild.

    • Region: Select your AWS region.

    • Create Project: Click Create build project.

      • Project Name: mywebapp-build

      • Environment:

        • Managed image: Ubuntu

        • Runtime: Standard

        • Image: aws/codebuild/standard:5.0 (or a recent Docker-enabled image)

        • Service role: Create a new service role or use an existing one with permissions for ECR (push/pull) and S3 (for artifacts).

      • Buildspec: Define your build process using a buildspec.yml file in your repository.

    Example buildspec.yml (for CI):

    # buildspec.yml
    version: 0.2
    
    phases:
      install:
        runtime-versions:
          nodejs: 18 # Or other language runtime
        commands:
          - echo "Installing dependencies..."
          - npm install
          - apt-get update && apt-get install -y gettext # For envsubst to replace placeholders
      pre_build:
        commands:
          - echo "Running tests..."
          - npm test # Run unit/integration tests
          - echo "Logging in to Amazon ECR..."
          - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
          - REPOSITORY_URI=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME
      build:
        commands:
          - echo "Building the Docker image..."
          - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
          - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $REPOSITORY_URI:$IMAGE_TAG
          - echo "Replacing image tag in Kubernetes manifests..."
          - envsubst < kubernetes/deployment.yaml > kubernetes/deployment.output.yaml # Use envsubst to replace placeholders
      post_build:
        commands:
          - echo "Pushing the Docker image to ECR..."
          - docker push $REPOSITORY_URI:$IMAGE_TAG
          - echo "Build and image push complete!"
    
    artifacts:
      files:
        - kubernetes/deployment.output.yaml # Output the modified manifest
        - kubernetes/service.yaml
        - kubernetes/ingress.yaml # Include other manifests
    
    • Note: IMAGE_REPO_NAME and IMAGE_TAG (which will be latest or $(CODEBUILD_RESOLVED_SOURCE_VERSION)) are environment variables passed to CodeBuild.

    • Security Best Practice: Integrate container image scanning (e.g., Clair, Trivy, Amazon ECR Image Scanning) in the post_build phase of CodeBuild and potentially fail the build if critical vulnerabilities are found.

  5. Deploy Stage (EKS Deployment):

    • Deploy Provider: Choose Amazon EKS.

    • Region: Select your AWS region.

    • Input Artifacts: Select the BuildArtifact from the previous stage.

    • Cluster Name: Select your EKS cluster name (mywebappeks).

    • Namespace: Specify the Kubernetes namespace (e.g., default, dev, staging, prod).

    • Manifest Files: List the manifest files to deploy (e.g., kubernetes/deployment.output.yaml, kubernetes/service.yaml, kubernetes/ingress.yaml).

    • Image (Optional): You can explicitly pass the image URI if your manifest isn't templated.

    • Deployment Strategy: CodePipeline supports rolling updates directly for EKS. For Blue/Green or Canary deployments, integrate with tools like AWS CodeDeploy (for ECS/EC2) or more advanced Kubernetes deployment tools like Argo Rollouts or Istio with appropriate integration into CodePipeline via Lambda functions or custom actions.

    • Rollback Strategy: Implement rollback by pushing a previous stable image version through the pipeline, or define a manual rollback action in CodePipeline.

2.3.4 Step 4: Monitoring, Logging, and Security Integration

  1. Amazon CloudWatch & Container Insights: Enable Container Insights for your EKS cluster to collect metrics and logs from containers, pods, and nodes.

    # Ensure your EKS cluster has the CloudWatch agent deployed or enable Container Insights via console/CLI
    aws eks update-addon --cluster-name mywebappeks --addon-name amazon-cloudwatch-observability --resolve-conflicts OVERWRITE --region us-east-1
    
  2. AWS CloudTrail: Automatically logs API calls across your AWS account, providing an audit trail for all actions on EKS and related services.

  3. Amazon GuardDuty: A threat detection service that continuously monitors for malicious activity and unauthorized behavior.

  4. AWS Security Hub: Provides a comprehensive view of your security alerts and compliance posture across AWS accounts.

  5. IAM Roles for Service Accounts (IRSA): Best practice for EKS to grant Kubernetes service accounts fine-grained AWS IAM permissions, minimizing the blast radius of compromised pods.

  6. Network Policies: Implement Kubernetes Network Policies to control traffic flow between pods within the EKS cluster.

  7. VPC Security Groups: Configure security groups for EKS nodes and load balancers to control inbound/outbound traffic.

Conclusion

Implementing CI/CD for cloud web applications on Kubernetes, whether on Azure AKS or AWS EKS, significantly enhances development velocity, improves code quality, and ensures reliable deployments. Both Azure DevOps and AWS DevOps services offer comprehensive, integrated toolchains that support the entire CI/CD lifecycle, from source code management and automated builds to containerization, deployment orchestration, and continuous monitoring. By following these planning and implementation steps, organizations can leverage the full power of Kubernetes in a streamlined and automated fashion.

No comments: