Skip to main content

ADR-014-v4: Deployment Pipeline - Part 2 (Technical)

Document Specification Block​

Document: ADR-014-v4-deployment-pipeline-part2-technical
Version: 1.0.0
Purpose: Constrain AI implementation with exact technical specifications for deployment pipeline
Audience: AI agents, developers implementing the system
Date Created: 2025-09-01
Date Modified: 2025-09-01
QA Review Date: Pending
Status: DRAFT

Table of Contents​

  1. Constraints
  2. Dependencies
  3. Component Architecture
  4. Data Models
  5. Implementation Patterns
  6. API Specifications
  7. Testing Requirements
  8. Performance Benchmarks
  9. Security Controls
  10. Logging and Error Handling
  11. References
  12. Approval Signatures

1. Constraints​

CONSTRAINT: Zero-Downtime Deployment​

All deployments MUST maintain 100% uptime. No service interruption allowed.

CONSTRAINT: Sub-4-Minute Builds​

Build and deployment pipeline MUST complete within 4 minutes for standard changes.

CONSTRAINT: Automatic Rollback​

Failed deployments MUST automatically rollback within 30 seconds of health check failure.

CONSTRAINT: Multi-Region Consistency​

Deployments MUST maintain consistency across all regions with <5 second lag.

CONSTRAINT: Audit Compliance​

Every deployment action MUST be logged with full traceability for SOC2 compliance.

↑ Back to Top

2. Dependencies​

cargo.toml Dependencies​

[dependencies]
# Cloud SDK
google-cloud-sdk = { version = "0.25", features = ["storage", "build", "run"] }

# Container tools
bollard = "0.16" # Docker API
kaniko = "0.1" # Container builder

# Deployment orchestration
k8s-openapi = { version = "0.20", features = ["v1_28"] }
kube = { version = "0.87", features = ["runtime", "derive"] }

# Monitoring
prometheus = { version = "0.13", features = ["process"] }
opentelemetry = { version = "0.21", features = ["trace", "metrics"] }

# Core
tokio = { version = "1.35", features = ["full"] }
anyhow = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
uuid = { version = "1.6", features = ["v4", "serde"] }
chrono = { version = "0.4", features = ["serde"] }

↑ Back to Top

3. Component Architecture​

// File: src/deployment/pipeline_service.rs
use std::sync::Arc;
use anyhow::Result;

pub struct DeploymentPipeline {
build_service: Arc<BuildService>,
deployment_service: Arc<DeploymentService>,
health_checker: Arc<HealthChecker>,
rollback_manager: Arc<RollbackManager>,
audit_logger: Arc<AuditLogger>,
}

// File: src/deployment/pipeline_service.rs
impl DeploymentPipeline {
pub async fn deploy(&self, request: DeploymentRequest) -> Result<DeploymentResult> {
// 1. Build stage
let build_result = self.build_service
.build_with_cache(&request.source)
.await?;

// 2. Security scan
self.security_scan(&build_result).await?;

// 3. Blue-green deployment
let deployment = self.deployment_service
.deploy_blue_green(&build_result, &request.target)
.await?;

// 4. Health validation
match self.health_checker.validate(&deployment).await {
Ok(_) => {
// 5. Traffic switch
self.deployment_service.switch_traffic(&deployment).await?;
self.audit_logger.log_success(&deployment).await?;
Ok(deployment.into())
}
Err(e) => {
// 6. Auto rollback
self.rollback_manager.execute(&deployment).await?;
self.audit_logger.log_rollback(&deployment, &e).await?;
Err(e)
}
}
}
}

↑ Back to Top

4. Data Models​

Deployment Models​

// File: src/models/deployment.rs
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DeploymentRequest {
pub id: Uuid,
pub source: SourceConfig,
pub target: TargetEnvironment,
pub strategy: DeploymentStrategy,
pub metadata: DeploymentMetadata,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SourceConfig {
pub repository: String,
pub branch: String,
pub commit: String,
pub dockerfile: Option<String>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum DeploymentStrategy {
BlueGreen { switch_delay_seconds: u32 },
Canary { stages: Vec<CanaryStage> },
Rolling { max_surge: u32, max_unavailable: u32 },
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HealthCheck {
pub endpoint: String,
pub interval_seconds: u32,
pub timeout_seconds: u32,
pub success_threshold: u32,
pub failure_threshold: u32,
}

↑ Back to Top

5. Implementation Patterns​

Build Optimization​

// File: src/deployment/build_service.rs
pub struct BuildService {
cache_bucket: String,
registry: String,
machine_type: String,
}

impl BuildService {
pub async fn build_with_cache(&self, source: &SourceConfig) -> Result<BuildResult> {
let config = CloudBuildConfig {
steps: vec![
// Step 1: Restore cache
BuildStep {
name: "gcr.io/cloud-builders/gsutil",
args: vec![
"cp",
&format!("gs://{}/cache.tar.gz", self.cache_bucket),
"cache.tar.gz"
],
},
// Step 2: Build with cargo-chef
BuildStep {
name: "gcr.io/kaniko-project/executor",
args: vec![
"--dockerfile=Dockerfile",
"--cache=true",
"--cache-ttl=168h",
&format!("--destination={}/api:$COMMIT_SHA", self.registry),
],
},
// Step 3: Save cache
BuildStep {
name: "gcr.io/cloud-builders/gsutil",
args: vec![
"cp",
"target/release/deps/*",
&format!("gs://{}/", self.cache_bucket),
],
},
],
options: BuildOptions {
machine_type: "E2_HIGHCPU_8".to_string(),
disk_size_gb: 100,
substitution_option: "ALLOW_LOOSE",
},
timeout: "600s",
};

self.execute_build(config).await
}
}

Blue-Green Deployment​

// File: src/deployment/deployment_service.rs
impl DeploymentService {
pub async fn deploy_blue_green(
&self,
build: &BuildResult,
target: &TargetEnvironment,
) -> Result<Deployment> {
// 1. Deploy to green environment
let green_revision = self.deploy_revision(
&build.image,
&format!("{}-green", target.service_name),
0, // No traffic initially
).await?;

// 2. Run smoke tests
self.run_smoke_tests(&green_revision).await?;

// 3. Prepare for switch
Ok(Deployment {
id: Uuid::new_v4(),
blue_revision: self.get_current_revision(&target.service_name).await?,
green_revision,
status: DeploymentStatus::AwaitingSwitch,
created_at: Utc::now(),
})
}

pub async fn switch_traffic(&self, deployment: &Deployment) -> Result<()> {
let traffic_config = TrafficConfig {
revisions: vec![
(deployment.green_revision.clone(), 100),
(deployment.blue_revision.clone(), 0),
],
};

self.update_traffic(traffic_config).await
}
}

↑ Back to Top

6. API Specifications​

Deployment Endpoints​

// File: src/api/handlers/deployment.rs
use actix_web::{web, HttpResponse, Result};

#[post("/api/v1/deploy")]
pub async fn trigger_deployment(
web::Json(request): web::Json<DeploymentRequest>,
pipeline: web::Data<Arc<DeploymentPipeline>>,
claims: Claims,
) -> Result<HttpResponse> {
// Validate permissions
if !claims.has_permission("deployment:create") {
return Ok(HttpResponse::Forbidden().json(json!({
"error": "insufficient_permissions"
})));
}

match pipeline.deploy(request.into_inner()).await {
Ok(result) => Ok(HttpResponse::Ok().json(result)),
Err(e) => Ok(HttpResponse::InternalServerError().json(json!({
"error": "deployment_failed",
"message": e.to_string()
})))
}
}

#[post("/api/v1/rollback/{deployment_id}")]
pub async fn rollback_deployment(
path: web::Path<Uuid>,
rollback_manager: web::Data<Arc<RollbackManager>>,
claims: Claims,
) -> Result<HttpResponse> {
let result = rollback_manager
.rollback(path.into_inner(), claims.user_id)
.await?;

Ok(HttpResponse::Ok().json(result))
}

↑ Back to Top

7. Testing Requirements​

Test Coverage Requirements​

  • Unit Test Coverage: ≥95% of deployment logic
  • Integration Test Coverage: ≥90% of pipeline flows
  • E2E Test Coverage: All critical deployment paths
  • Chaos Test Coverage: Network failures, partial deployments

Integration Tests​

#[cfg(test)]
mod tests {
use super::*;

#[tokio::test]
async fn test_blue_green_deployment() {
let pipeline = setup_test_pipeline().await;

let request = DeploymentRequest {
source: SourceConfig {
repository: "test-repo",
branch: "main",
commit: "abc123",
dockerfile: None,
},
target: TargetEnvironment {
service_name: "api",
region: "us-central1",
project_id: "test-project",
},
strategy: DeploymentStrategy::BlueGreen {
switch_delay_seconds: 30
},
metadata: Default::default(),
};

let result = pipeline.deploy(request).await.unwrap();
assert_eq!(result.status, DeploymentStatus::Success);
}

#[tokio::test]
async fn test_automatic_rollback() {
let pipeline = setup_test_pipeline().await;
let failing_request = create_failing_deployment_request();

let result = pipeline.deploy(failing_request).await;
assert!(result.is_err());

// Verify rollback occurred
let status = pipeline.get_deployment_status().await.unwrap();
assert_eq!(status.rollback_count, 1);
}
}

↑ Back to Top

8. Performance Benchmarks​

Required Metrics​

const BUILD_TIME_TARGET_MS: u64 = 240_000; // 4 minutes
const ROLLBACK_TIME_TARGET_MS: u64 = 30_000; // 30 seconds
const HEALTH_CHECK_TIMEOUT_MS: u64 = 5_000;

pub struct PerformanceValidator {
pub fn validate_deployment_performance(&self, metrics: &DeploymentMetrics) -> ValidationResult {
let mut result = ValidationResult::default();

// Build time
result.build_time_ok = metrics.build_duration_ms <= BUILD_TIME_TARGET_MS;

// Rollback time
if let Some(rollback_ms) = metrics.rollback_duration_ms {
result.rollback_time_ok = rollback_ms <= ROLLBACK_TIME_TARGET_MS;
}

// Health check responsiveness
result.health_check_ok = metrics.health_check_duration_ms <= HEALTH_CHECK_TIMEOUT_MS;

result
}
}

↑ Back to Top

9. Security Controls​

Deployment Security​

// File: src/deployment/security.rs
pub struct DeploymentSecurity {
scanner: Arc<ContainerScanner>,
policy_engine: Arc<PolicyEngine>,
}

impl DeploymentSecurity {
pub async fn validate_deployment(&self, build: &BuildResult) -> Result<()> {
// Container scanning
let scan_result = self.scanner.scan_image(&build.image).await?;
if scan_result.critical_vulnerabilities > 0 {
return Err(anyhow!("Critical vulnerabilities found"));
}

// Policy validation
self.policy_engine.validate_deployment_policy(build).await?;

// Sign image
self.sign_container_image(&build.image).await?;

Ok(())
}
}

↑ Back to Top

10. Logging and Error Handling​

Deployment Logging​

// File: src/deployment/logging.rs
use tracing::{info, error, instrument};

#[instrument(skip(self))]
pub async fn log_deployment_event(&self, event: DeploymentEvent) {
let entry = json!({
"timestamp": Utc::now(),
"event_type": event.event_type,
"deployment_id": event.deployment_id,
"service": event.service_name,
"region": event.region,
"user": event.triggered_by,
"status": event.status,
"duration_ms": event.duration_ms,
});

info!(deployment_event = ?entry, "Deployment event");
}

Error Handling​

#[derive(thiserror::Error, Debug)]
pub enum DeploymentError {
#[error("Build failed: {0}")]
BuildFailed(String),

#[error("Health check failed after {attempts} attempts")]
HealthCheckFailed { attempts: u32 },

#[error("Rollback failed: {0}")]
RollbackFailed(String),

#[error("Security scan failed: {vulnerabilities} critical vulnerabilities")]
SecurityScanFailed { vulnerabilities: u32 },
}

↑ Back to Top

11. References​

Version Compatibility​

  • Google Cloud SDK: 0.25+ for Cloud Build v2 API
  • Kubernetes: 1.28+ for traffic management features
  • Cloud Run: Latest for blue-green deployments

↑ Back to Top

12. Approval Signatures​

Technical Sign-off​

ComponentOwnerApprovedDate
ArchitectureSession5✓2025-09-01
ImplementationPending--
Security ReviewPending--
Performance TestPending--

Implementation Checklist​

  • Pipeline service implemented
  • Build optimization with caching
  • Blue-green deployment logic
  • Health check validation
  • Automatic rollback mechanism
  • Security scanning integration
  • API endpoints tested
  • Performance benchmarks met
  • Monitoring configured

↑ Back to Top