Enterprise ArchitectureZachman Framework

Zachman Sub-Contractor Row: Executable Code and Deployment Explained

TT
TopicTrick Team
Zachman Sub-Contractor Row: Executable Code and Deployment Explained

Zachman Sub-Contractor Row: Executable Code and Deployment Explained

The Sub-Contractor row (Row 5) is the fifth perspective in the Zachman Framework matrix. It represents the developer/operator's perspective - the actual executable code, scripts, and deployment automation. If Row 4 says "here's how to build it," Row 5 says "here's the working code and deployment procedures."

The Sub-Contractor row is characterised by:

  • Executable: Code that runs; scripts that deploy
  • Version-controlled: All code checked into git or other VCS
  • Tested: Unit tests, integration tests, deployment tests
  • Detailed: Line-by-line code; can be hundreds of thousands of lines
  • Volatile: Changes constantly as features are added and bugs fixed

This is where the rubber meets the road - where abstract architecture becomes working systems.


What Does the Sub-Contractor Row Cover?

The Sub-Contractor row addresses all six interrogatives, at the executable code level:

InterrogativeSub-Contractor (Row 5)Example
WhatDDL scripts, data loading scriptsCREATE TABLE scripts, seed data
HowApplication source code, business logicJava, Python, JavaScript code files
WhereDeployment scripts, infrastructure-as-codeTerraform, Kubernetes manifests, Docker
WhoIdentity provisioning scriptsUser provisioning automation, IAM code
WhenJob scheduling code, event handlersCron jobs, Lambda functions, Kafka consumers
WhyConfiguration files, policies as codeYAML configs, policy definitions, feature flags

The Six Columns in the Sub-Contractor Row

Column 1: Sub-Contractor/What - DDL and Data Scripts

Question: What are the actual database creation and data loading scripts?

Artefacts:

  • DDL (Data Definition Language) scripts
  • Data loading scripts (seed data, migrations)
  • Backup/recovery scripts
  • Database maintenance scripts

Characteristics:

  • Fully executable SQL or database-specific language
  • Version-controlled in git
  • Idempotent (safe to run multiple times)
  • Includes comments explaining non-obvious logic

Example:

sql
-- File: scripts/01_create_tables.sql
-- Version: 1.0
-- Description: Create initial database schema for order management

-- Create customers table
CREATE TABLE IF NOT EXISTS customers (
  customer_id BIGSERIAL PRIMARY KEY,
  first_name VARCHAR(100) NOT NULL,
  last_name VARCHAR(100) NOT NULL,
  email VARCHAR(255) NOT NULL UNIQUE,
  phone VARCHAR(20),
  customer_segment VARCHAR(50) NOT NULL DEFAULT 'SMB',
  created_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  modified_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT chk_first_name CHECK (first_name <> ''),
  CONSTRAINT chk_email CHECK (email <> '')
);

CREATE INDEX idx_customers_email ON customers(email);
CREATE INDEX idx_customers_segment ON customers(customer_segment);

-- Create accounts table
CREATE TABLE IF NOT EXISTS accounts (
  account_id BIGSERIAL PRIMARY KEY,
  customer_id BIGINT NOT NULL REFERENCES customers(customer_id),
  account_type VARCHAR(50) NOT NULL,
  status VARCHAR(50) NOT NULL DEFAULT 'ACTIVE',
  balance NUMERIC(18,2) NOT NULL DEFAULT 0,
  created_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT chk_balance CHECK (balance >= 0)
);

CREATE INDEX idx_accounts_customer ON accounts(customer_id);

-- Create transactions table
CREATE TABLE IF NOT EXISTS transactions (
  transaction_id BIGSERIAL PRIMARY KEY,
  account_id BIGINT NOT NULL REFERENCES accounts(account_id),
  amount NUMERIC(18,2) NOT NULL,
  type VARCHAR(50) NOT NULL,
  status VARCHAR(50) NOT NULL DEFAULT 'PENDING',
  transaction_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT chk_amount CHECK (amount > 0)
);

CREATE INDEX idx_transactions_account ON transactions(account_id);
CREATE INDEX idx_transactions_date ON transactions(transaction_date DESC);

-- Grant permissions
GRANT SELECT, INSERT, UPDATE ON customers TO app_user;
GRANT SELECT, INSERT, UPDATE ON accounts TO app_user;
GRANT SELECT, INSERT, UPDATE ON transactions TO app_user;

Data loading script:

python
# File: scripts/seed_data.py
#!/usr/bin/env python3
"""Load initial seed data into production database."""

import psycopg2
from datetime import datetime

def seed_database():
    conn = psycopg2.connect(
        host="localhost",
        database="orders_db",
        user="app_user",
        password="***"
    )
    
    cursor = conn.cursor()
    
    try:
        # Load customers
        cursor.execute("""
            INSERT INTO customers (first_name, last_name, email, customer_segment)
            VALUES 
                ('John', 'Doe', 'john@example.com', 'SMB'),
                ('Jane', 'Smith', 'jane@example.com', 'Mid-market'),
                ('Bob', 'Wilson', 'bob@example.com', 'SMB')
        """)
        
        # Load products
        cursor.execute("""
            INSERT INTO products (name, price, category)
            VALUES 
                ('Product A', 99.99, 'Category1'),
                ('Product B', 199.99, 'Category2')
        """)
        
        conn.commit()
        print("Seed data loaded successfully")
        
    except Exception as e:
        conn.rollback()
        print(f"Error loading seed data: {e}")
        raise
    
    finally:
        cursor.close()
        conn.close()

if __name__ == '__main__':
    seed_database()

Why: Enables reproducible database creation and deployment.


Column 2: Sub-Contractor/How - Application Source Code

Question: What is the actual application code implementing business logic?

Artefacts:

  • Source code files (Java, Python, JavaScript, etc.)
  • Unit tests
  • Integration tests
  • API documentation

Characteristics:

  • Hundreds to millions of lines of code
  • Version-controlled in git
  • Follows coding standards and patterns
  • Includes tests and documentation

Example (Java/Spring Boot):

java
// File: src/main/java/com/company/orders/OrderService.java
package com.company.orders;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class OrderService {
    
    private OrderRepository orderRepository;
    private InventoryService inventoryService;
    private PaymentService paymentService;
    
    public OrderService(OrderRepository repo, 
                       InventoryService inventory,
                       PaymentService payment) {
        this.orderRepository = repo;
        this.inventoryService = inventory;
        this.paymentService = payment;
    }
    
    @Transactional
    public Order placeOrder(PlaceOrderRequest request) {
        // Validate inventory
        InventoryCheckResult check = inventoryService.checkInventory(
            request.getItems()
        );
        
        if (!check.isAvailable()) {
            throw new OutOfStockException("Items not available");
        }
        
        // Process payment
        PaymentResult payment = paymentService.processPayment(
            request.getAmount(),
            request.getPaymentMethod()
        );
        
        if (!payment.isSuccessful()) {
            throw new PaymentFailedException("Payment declined");
        }
        
        // Create order
        Order order = new Order();
        order.setCustomerId(request.getCustomerId());
        order.setStatus(OrderStatus.CONFIRMED);
        order.setCreatedDate(LocalDateTime.now());
        
        return orderRepository.save(order);
    }
}

Unit test:

java
// File: src/test/java/com/company/orders/OrderServiceTest.java
package com.company.orders;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class OrderServiceTest {
    
    @Mock
    private OrderRepository orderRepository;
    
    @Mock
    private InventoryService inventoryService;
    
    @Mock
    private PaymentService paymentService;
    
    @InjectMocks
    private OrderService orderService;
    
    @Test
    public void testPlaceOrder_Success() {
        // Arrange
        PlaceOrderRequest request = createValidRequest();
        when(inventoryService.checkInventory(any()))
            .thenReturn(InventoryCheckResult.available());
        when(paymentService.processPayment(anyDouble(), any()))
            .thenReturn(PaymentResult.success());
        
        // Act
        Order order = orderService.placeOrder(request);
        
        // Assert
        assertNotNull(order);
        assertEquals(OrderStatus.CONFIRMED, order.getStatus());
        verify(orderRepository, times(1)).save(any());
    }
    
    @Test
    public void testPlaceOrder_OutOfStock() {
        // Arrange
        PlaceOrderRequest request = createValidRequest();
        when(inventoryService.checkInventory(any()))
            .thenReturn(InventoryCheckResult.unavailable());
        
        // Act & Assert
        assertThrows(OutOfStockException.class, 
            () -> orderService.placeOrder(request));
    }
}

Why: Makes business logic executable and testable.


Column 3: Sub-Contractor/Where - Deployment Scripts and Infrastructure-as-Code

Question: How is the system deployed to infrastructure?

Artefacts:

  • Terraform/CloudFormation scripts
  • Kubernetes manifests (YAML)
  • Docker files
  • CI/CD pipeline configurations
  • Deployment procedures

Characteristics:

  • Fully executable (can be run to deploy)
  • Version-controlled in git
  • Idempotent (safe to run multiple times)
  • Includes monitoring and logging configuration

Example (Terraform):

hcl
# File: terraform/main.tf
provider "aws" {
  region = "us-east-1"
}

# Create VPC
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  tags = {
    Name = "order-system-vpc"
  }
}

# Create public subnets
resource "aws_subnet" "public_1a" {
  vpc_id                  = aws_vpc.main.id
  cidr_block              = "10.0.1.0/24"
  availability_zone       = "us-east-1a"
  map_public_ip_on_launch = true
}

# Create RDS database
resource "aws_db_instance" "main" {
  allocated_storage    = 100
  storage_type         = "gp2"
  engine                = "postgres"
  engine_version        = "13.7"
  instance_class        = "db.r5.large"
  db_name               = "orders_db"
  username              = var.db_username
  password              = var.db_password
  multi_az              = true
  backup_retention_period = 30
  skip_final_snapshot   = false
  
  tags = {
    Name = "orders-db"
  }
}

# Create ElastiCache Redis cluster
resource "aws_elasticache_cluster" "redis" {
  cluster_id           = "orders-cache"
  engine                = "redis"
  node_type             = "cache.r6g.xlarge"
  num_cache_nodes       = 3
  parameter_group_name  = "default.redis6.x"
  port                  = 6379
  engine_version        = "6.2"
  
  tags = {
    Name = "orders-cache"
  }
}

# Outputs
output "db_endpoint" {
  value = aws_db_instance.main.endpoint
}

output "redis_endpoint" {
  value = aws_elasticache_cluster.redis.cache_nodes[0].address
}

Example (Kubernetes manifest):

yaml
# File: k8s/order-service-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service
  labels:
    app: order-service
spec:
  replicas: 3
  selector:
    matchLabels:
      app: order-service
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
      - name: order-service
        image: myregistry.azurecr.io/order-service:1.0.0
        ports:
        - containerPort: 8080
        env:
        - name: DB_HOST
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: host
        - name: DB_USER
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: username
        resources:
          requests:
            memory: "512Mi"
            cpu: "500m"
          limits:
            memory: "1Gi"
            cpu: "1000m"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5

---
apiVersion: v1
kind: Service
metadata:
  name: order-service
spec:
  selector:
    app: order-service
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  type: LoadBalancer

Why: Enables reproducible, automated deployments.


Column 4: Sub-Contractor/Who - User Provisioning Scripts

Question: How are users provisioned and access controlled?

Artefacts:

  • User provisioning scripts (create/delete users)
  • Identity and Access Management (IAM) policies
  • Secret management code

Characteristics:

  • Automated provisioning/de-provisioning
  • Auditable (logs all provisioning actions)
  • Enforces least-privilege access

Example:

python
# File: scripts/provision_user.py
#!/usr/bin/env python3
"""Provision a new user in all systems."""

import boto3
import ldap3

def provision_user(username, email, department):
    """Provision user in AD, AWS IAM, and database."""
    
    # 1. Create Active Directory user
    create_ad_user(username, email, department)
    
    # 2. Create AWS IAM user
    iam = boto3.client('iam')
    iam.create_user(UserName=username)
    
    # 3. Attach policy based on department
    policy = get_policy_for_department(department)
    iam.attach_user_policy(
        UserName=username,
        PolicyArn=policy['arn']
    )
    
    # 4. Create database user
    create_database_user(username, department)
    
    # 5. Log provisioning
    audit_log(
        action='user_provisioned',
        username=username,
        email=email,
        department=department
    )

def create_ad_user(username, email, department):
    """Create user in Active Directory."""
    server = ldap3.Server('ldap://dc.example.com')
    conn = ldap3.Connection(server, user='admin', password='***')
    
    user_dn = f'cn={username},ou={department},dc=example,dc=com'
    attributes = {
        'objectClass': ['person', 'organizationalPerson', 'user'],
        'cn': username,
        'sAMAccountName': username,
        'mail': email,
        'departmentNumber': department
    }
    
    conn.add(user_dn, attributes=attributes)
    conn.unbind()

Why: Enables secure, auditable user management.


Column 5: Sub-Contractor/When - Scheduling Jobs and Event Handlers

Question: What code implements scheduled jobs and event processing?

Artefacts:

  • Scheduled job code (batch processing)
  • Event handler code (for events in Row 3)
  • Message queue consumer code

Characteristics:

  • Executable (runs on schedule or on events)
  • Robust error handling and retry logic
  • Logging and monitoring

Example:

python
# File: src/jobs/nightly_order_processing.py
import logging
from datetime import datetime, timedelta

logger = logging.getLogger(__name__)

def nightly_order_processing():
    """
    Nightly batch job: Process confirmed orders for shipment.
    Runs daily at 22:00 UTC.
    """
    
    try:
        logger.info("Starting nightly order processing job")
        
        # Get confirmed orders from last 24 hours
        yesterday = datetime.now() - timedelta(days=1)
        orders = get_confirmed_orders_since(yesterday)
        
        logger.info(f"Processing {len(orders)} confirmed orders")
        
        processed_count = 0
        for order in orders:
            try:
                # Assign to warehouse bin
                bin_assignment = assign_to_bin(order)
                
                # Update order status
                update_order_status(order['id'], 'PICKED', bin_assignment)
                
                # Publish event
                publish_event('OrderPicked', {
                    'order_id': order['id'],
                    'bin': bin_assignment
                })
                
                processed_count += 1
                
            except Exception as e:
                logger.error(f"Error processing order {order['id']}: {e}")
                publish_event('OrderPickingFailed', {
                    'order_id': order['id'],
                    'error': str(e)
                })
        
        logger.info(f"Successfully processed {processed_count} orders")
        
    except Exception as e:
        logger.error(f"Nightly order processing failed: {e}")
        send_alert(f"Order processing failure: {e}")
        raise

Why: Enables reliable, auditable batch and event processing.


Column 6: Sub-Contractor/Why - Configuration and Policy Code

Question: How are policies and configurations implemented?

Artefacts:

  • Configuration files (YAML, JSON, environment variables)
  • Feature flag implementations
  • Security policies (as code)
  • Compliance controls (as code)

Characteristics:

  • Version-controlled (changes tracked)
  • Auditable (who changed what when)
  • Testable (can be validated before deployment)

Example:

yaml
# File: config/application.yaml
app:
  name: Order Management System
  version: 1.0.0

server:
  port: 8080
  timeout: 30s

database:
  host: ${DB_HOST}
  port: 5432
  name: orders_db
  pool_size: 20
  ssl: true

security:
  encryption:
    algorithm: AES-256-GCM
    key: ${ENCRYPTION_KEY}
  authentication:
    type: oauth2
    provider: auth0
  cors:
    allowed_origins:
      - https://example.com
      - https://app.example.com

compliance:
  gdpr:
    enabled: true
    data_retention_days: 90
  hipaa:
    enabled: false
  soc2:
    audit_logging: true

features:
  new_checkout: true
  guest_checkout: false
  wishlist: true
  
policies:
  password:
    min_length: 12
    require_uppercase: true
    require_numbers: true
    expiry_days: 90
  mfa:
    required_for_admins: true
    grace_period_days: 14

Why: Enables configuration and policy to be version-controlled and audited.


Sub-Contractor Row in Practice

In a real enterprise architecture initiative:

  1. Development: Developers write code based on Row 4 specifications.
  2. Testing: QA tests code against Row 3 requirements.
  3. Version control: All code checked into git with clear commit messages.
  4. CI/CD: Automated builds, tests, and deployments on code changes.
  5. Deployment: Code deployed to Row 6 (live system) using Row 5 deployment scripts.
  6. Monitoring: Operational metrics tracked and alerted on.

Sub-Contractor Row vs. Enterprise Row

Important distinction:

  • Sub-Contractor (Row 5): "Here's the code" (ready to deploy)
  • Enterprise (Row 6): "Here's what's actually running" (live system)

Row 5 is the blueprint; Row 5 is what gets deployed; Row 6 is what's actually executing.


Common Mistakes in the Sub-Contractor Row

  1. No version control: Code not checked in; changes not tracked.

  2. No tests: Code deployed without automated tests; regressions common.

  3. Manual deployments: Deployment processes not automated; errors common.

  4. No documentation: Code so complex that only original developer understands it.

  5. No logging/monitoring: System fails; nobody knows why or when.


Sub-Contractor Row Best Practices

  1. Version control everything: All code, scripts, configurations in git.

  2. Automate tests: Unit tests, integration tests, deployed automatically on every commit.

  3. Automate deployments: CI/CD pipeline deploys automatically on successful tests.

  4. Log everything: All actions logged; searchable, auditable logs.

  5. Monitor everything: Key metrics monitored; alerts fired on anomalies.


Example: Sub-Contractor Row for E-commerce

text
Source Code:
  - Backend: src/main/java (Spring Boot, Gradle)
  - Frontend: src/main/web (React, TypeScript)
  - Tests: src/test (unit and integration tests)
  - Scripts: scripts/ (database, provisioning, deployment)

Version Control:
  - Git repository on GitHub
  - Main branch: production code
  - Develop branch: development code
  - Feature branches: temporary for features

CI/CD Pipeline:
  - Build: Maven/Gradle compiles code
  - Test: JUnit tests run (200+ tests)
  - Quality: SonarQube analyzes code (min 80% coverage)
  - Package: Docker image created
  - Deploy: Kubernetes manifests deployed to cluster

Deployment:
  - Blue-green deployment (zero downtime)
  - Automated rollback if health checks fail
  - Database migrations run automatically (Flyway)

Monitoring:
  - Application logs: CloudWatch / ELK
  - Metrics: Prometheus, Grafana
  - Alerting: PagerDuty for critical issues

Key Takeaways

  1. Sub-Contractor row is where architecture becomes code: Executable, testable, version-controlled.

  2. Everything should be automated: Builds, tests, deployments - repeatability is key.

  3. Version control is non-negotiable: Every change tracked, every deployment auditable.

  4. Testing is part of the code: Not optional; automate it.

  5. Monitoring must be comprehensive: If you can't see it, you can't manage it.


Next Steps

  • Explore Enterprise Row (Row 6) to see live system metrics and reality.
  • Read CI/CD Best Practices for deployment automation.
  • Jump to Complete Matrix to see all perspectives together.

The Sub-Contractor row is where teams get work done. Master it, and you ensure systems are built reliably, tested thoroughly, and deployed safely.


Meta Keywords: Zachman Sub-Contractor row, source code, deployment, CI/CD, automation, DevOps.