Deployment Manifests Guide๏ƒ

Learn how to enable, interpret, and use deployment manifests for compliance, auditing, and operational visibility.


Overview๏ƒ

Deployment manifests are immutable snapshots created at two points in your workflow:

  1. Build time โ€” strata build run captures the configuration and build outputs (artifacts, SBOM)

  2. Deploy time โ€” strata deploy run captures the full deployment record (provisioner outputs, stage results)

Think of manifests as evidence โ€” a complete record of what was intended (build) and what actually happened (deploy). Together, they form your compliance audit trail.


What is a Deployment Manifest?๏ƒ

Build Manifest๏ƒ

A build manifest is created by strata build run and captures:

  • Configuration snapshot โ€” Full platform.json with all resolved values

  • Build artifacts โ€” Terraform, Ansible, Helm, Docker Compose files (if generated)

  • Repository state โ€” Git commits for all solution repositories

  • Bill of Materials โ€” SBOM with component versions

  • Build environment โ€” Timestamp, user, version, environment variables

  • Policy results โ€” Any policy engine outputs (if enabled)

Purpose: Proves what was built, by whom, when, and from which source code.

Example use case: Your security team asks, โ€œWhat was in the build artifact that went to staging?โ€ You show them the build manifest with the exact platform.json snapshot and commit SHAs.

Deploy Manifest๏ƒ

A deploy manifest is created by strata deploy run and captures everything that was deployed:

  • Exact configuration โ€” Full platform.json snapshot

  • Pinned versions โ€” Git commits for all repositories

  • Infrastructure state โ€” Provisioners, backends, resource counts

  • Container images โ€” Image references with digests

  • Audit metadata โ€” Timestamp, user, deployment status, stage results

  • Bill of Materials โ€” SBOM with component versions and vulnerabilities

The Build โ†’ Deploy Workflow๏ƒ

graph LR
    A["strata build run"] -->|generates| B["Build Manifest<br/>config + SBOM + repos"]
    B -->|input to| C["strata deploy run"]
    C -->|extends| D["Deploy Manifest<br/>build manifest + results"]
    D -->|compliance evidence| E["Audit Trail"]

Timeline:

  1. Build phase โ†’ Build manifest written to .strata/build/{deployment}/manifest.json

  2. Review & testing โ†’ Inspect build manifest before approving to deploy

  3. Deploy phase โ†’ Deploy manifest written to .strata/deployments/{deployment}/{version}/

  4. Audit โ†’ Both manifests available for compliance queries


Why Use Deployment Manifests?๏ƒ

Compliance & Audit๏ƒ

Regulatory requirements (NIS2, ISAE 3402 Type 2):

  • Immutable record of infrastructure changes

  • Proof of authorization (user who deployed, timestamp)

  • Version pinning (exact Git commits deployed)

  • Configuration snapshots for forensic analysis

Example: An auditor asks, โ€œWhat was deployed to production on June 15?โ€ You answer:

# Find the manifest
ls .strata/deployments/prod_deployment/v2.3.0/
# 2024-06-15T14:32:45Z.json

# Show it
jq '.spec.artifacts.repositories' 2024-06-15T14:32:45Z.json
# {
#   "xyz-infrastructure": {
#     "url": "git@github.com:acme/xyz-infra.git",
#     "ref": "v2.3.0",
#     "commit": "a1b2c3d4e5f6g7h8..."  โ† exact commit deployed
#   }
# }

Operational Visibility๏ƒ

Troubleshooting:

  • Compare manifests before/after a change to identify drift

  • Trace stage failures with per-stage timing and outputs

  • Correlate with Git history to understand what changed

Example:

# What changed between two deployments?
diff <(jq '.spec.artifacts.repositories' manifest1.json) \
     <(jq '.spec.artifacts.repositories' manifest2.json)

# What was the deployment status?
jq '.spec.status, .spec.stages[].status' manifest.json
# "success"
# "success"
# "success"

Rollback & Recovery๏ƒ

Manifest as rollback source:

# Extract pinned versions from the last-known-good deployment
jq '.spec.artifacts.repositories | to_entries | .[].value.commit' \
  previous_deployment.json > rollback_commits.txt

# Or extract the entire platform.json to reapply:
jq '.spec.artifacts.platform.content' good_manifest.json > platform.json.bak

Setup๏ƒ

1. Enable Manifests in Configuration๏ƒ

Create or update your configuration file to include manifest storage:

Local filesystem:

apiVersion: strata.huybrechts.xyz/v1
kind: configuration
meta:
  name: local_manifest_config
spec:
  manifest:
    type: local
    path: ".strata/deployments"

GitOps (state repository):

apiVersion: strata.huybrechts.xyz/v1
kind: configuration
meta:
  name: gitops_manifest_config
spec:
  repositories:
    - name: xyz-state-repo
      url: git@github.com:acme/xyz-state.git
      branch: main
      clone: true

  manifest:
    type: gitops
    path: "deployments"
    repository: xyz-state-repo
    branch: manifests
    tag: true

2. Reference in Your Deployment๏ƒ

Add the configuration to your deployment file:

apiVersion: strata.huybrechts.xyz/v1
kind: deployment
meta:
  name: prod_deployment
spec:
  configurations:
    - name: local_manifest_config  # or gitops_manifest_config
      source:
        type: local
        repository: /
        source_path: config/configurations/manifest_config.yaml

3. Deploy๏ƒ

strata deploy run -f deployments/prod.yaml

The manifest is written automatically upon completion (success or failure).


Reading a Manifest๏ƒ

Manifests are JSON files with this structure:

{
  "apiVersion": "strata.huybrechts.xyz/v1",
  "kind": "deployment-manifest",
  "meta": {
    "name": "prod_deployment",
    "labels": {
      "version": "2.3.0",
      "environment": "production"
    }
  },
  "spec": {
    "deployment_name": "prod_deployment",
    "workspace_name": "prod_workspace",
    "action": "deploy",
    "status": "success",
    "timestamp": "2024-06-17T10:45:33Z",
    "user": "ops-lead@acme.com",
    "platform_version": "1.2.0",
    
    "artifacts": {
      "platform": {
        "hash": "sha256:abc123...",
        "path": "build/platform.json",
        "content": { ... full platform.json ... }
      },
      
      "repositories": {
        "xyz-infrastructure": {
          "url": "git@github.com:acme/xyz-infra.git",
          "ref": "v2.3.0",
          "commit": "a1b2c3d4e5f6g7h8..."
        },
        "xyz-config": {
          "url": "git@github.com:acme/xyz-config.git",
          "ref": "main",
          "commit": "f7g8h9i0j1k2l3m4..."
        }
      },
      
      "images": [
        {
          "name": "traefik",
          "image": "docker.io/traefik:v3.0.1",
          "digest": "sha256:xyz789..."
        }
      ],
      
      "providers": [
        {
          "name": "tf_hetzner",
          "type": "terraform",
          "backend": {
            "type": "azurerm",
            "configuration": { ... }
          }
        }
      ],
      
      "sbom": {
        "path": "build/sbom.json",
        "format": "cyclonedx-1.6",
        "sha256": "sha256:def456...",
        "component_count": 47
      }
    },
    
    "stages": [
      {
        "name": "infrastructure",
        "status": "success",
        "duration_seconds": 125,
        "outputs": {
          "server_ip": "192.0.2.10",
          "load_balancer_fqdn": "lb.example.com"
        }
      },
      {
        "name": "configure",
        "status": "success",
        "duration_seconds": 45,
        "outputs": {}
      }
    ]
  }
}

Key Fields๏ƒ

Field

Purpose

spec.status

Deployment outcome (success or failure)

spec.timestamp

When deployment ran (UTC, ISO 8601)

spec.user

Who ran the deployment

spec.artifacts.platform.hash

SHA-256 of the entire configuration

spec.artifacts.repositories

Git commits for audit trail

spec.artifacts.images

Container image references + digests

spec.stages[].duration_seconds

How long each stage took

spec.stages[].outputs

Terraform outputs, Ansible facts, etc.

spec.artifacts.sbom

Bill of materials (vulnerabilities, etc.)


Common Tasks๏ƒ

List All Manifests๏ƒ

Using strata manifest CLI:

# List all available manifests
strata manifest list

# JSON output for scripting
strata manifest list --output json

# Filter by deployment
strata manifest list --deployment prod_deployment --output json

# Show last 5 manifests
strata manifest list --last 5

Manual filesystem traversal:

Local storage:

# List all manifests
find .strata/deployments -name "*.json" -type f | sort

# List just production deployments, newest first
find .strata/deployments/prod_deployment -name "*.json" | sort -r | head -5

GitOps storage:

# Clone the state repo
git clone git@github.com:acme/xyz-state.git
cd xyz-state

# List deployments
find deployments -name "*.json" | sort -r

View a Manifest๏ƒ

Using strata manifest CLI:

# Show manifest in console-friendly format
strata manifest show 2024-06-17T10:45:33Z.json

# JSON output
strata manifest show 2024-06-17T10:45:33Z.json --output json

# Query specific fields with jq
strata manifest show 2024-06-17T10:45:33Z.json --output json | \
  jq '.spec.artifacts.repositories'

Export Manifests for Compliance๏ƒ

Create compliance evidence package:

# Export all manifests with SBOM and platform.json
strata manifest export --output-dir ./compliance_package \
  --include-sbom \
  --include-platform

# Result:
# compliance_package/
#   manifests/
#     2024-06-17T10:45:33Z.json
#     2024-06-16T14:22:10Z.json
#   sboms/
#     2024-06-17T10:45:33Z-sbom.json
#   artifacts/
#     platform-2024-06-17T10:45:33Z.json

Compare Two Deployments๏ƒ

# Export both manifests to JSON
manifest1=$(strata manifest show m1.json --output json)
manifest2=$(strata manifest show m2.json --output json)

# What repositories changed?
diff <(echo "$manifest1" | jq -r '.spec.artifacts.repositories | keys[]' | sort) \
     <(echo "$manifest2" | jq -r '.spec.artifacts.repositories | keys[]' | sort)

# What commits changed?
diff <(echo "$manifest1" | jq '.spec.artifacts.repositories') \
     <(echo "$manifest2" | jq '.spec.artifacts.repositories')

Extract Terraform Outputs๏ƒ

# Get all stage outputs
jq '.spec.stages[] | select(.name == "infrastructure") | .outputs' manifest.json

# Get one specific output
jq '.spec.stages[] | select(.name == "infrastructure") | .outputs.server_ip' manifest.json

Check Deployment Duration๏ƒ

# Total duration across all stages
jq '[.spec.stages[].duration_seconds] | add' manifest.json

# Duration per stage
jq '.spec.stages[] | {name, duration_seconds}' manifest.json

Inspect SBOM๏ƒ

# Count components
jq '.spec.artifacts.sbom.component_count' manifest.json

# Get SBOM file
cat build/sbom.json | jq '.metadata.component'

Failed Deployment Details๏ƒ

# Check status
jq '.spec.status' failed_manifest.json

# Which stage failed?
jq '.spec.stages[] | select(.status != "success")' failed_manifest.json

# Get error details (if captured)
jq '.spec.stages[] | select(.status != "success") | .error' failed_manifest.json

GitOps Workflow๏ƒ

When using type: gitops, manifests are automatically committed and tagged:

# After deploy
strata deploy run -f prod.yaml

# In your state repository:
git log --oneline deployments/
# 2a3b4c5 strata: deployment manifest prod_deployment v2.3.0
# 1f2g3h4 strata: deployment manifest prod_deployment v2.2.9
# ...

# Tags are also created:
git tag -l "prod_deployment/*" | sort
# prod_deployment/v2.2.8
# prod_deployment/v2.2.9
# prod_deployment/v2.3.0

# Retrieve a manifest from a tag:
git show prod_deployment/v2.3.0:deployments/prod_deployment/v2.3.0/2024-06-17T10:45:33Z.json

Downstream Automation๏ƒ

GitOps manifests enable automatic downstream workflows:

# Compliance scanner watches the state repo
# On new manifest commit โ†’ scan SBOM for vulnerabilities
# On new tag โ†’ generate audit report

# Example: GitHub Actions on manifest push
on:
  push:
    paths:
      - 'deployments/**'
jobs:
  compliance-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Extract SBOM from manifest
        run: |
          manifest=$(ls -t deployments/prod_deployment/**/*.json | head -1)
          sbom_path=$(jq -r '.spec.artifacts.sbom.path' $manifest)
          # Run compliance scanner on sbom_path

Troubleshooting๏ƒ

Manifest Not Written๏ƒ

Check configuration:

# Verify the configuration exists
strata validate config/configurations/manifest_config.yaml

# Check for errors in the build log
strata deploy run -f prod.yaml --verbose 2>&1 | grep -i manifest

Missing manifest section:

If you see Manifest configuration not found, the deployment doesnโ€™t reference a configuration with manifest settings. Add it:

spec:
  configurations:
    - name: my_manifest_config
      source:
        type: local
        repository: /
        source_path: config/configurations/manifest.yaml

GitOps Push Failed๏ƒ

# Check git credentials
git clone git@github.com:acme/xyz-state.git

# Verify branch exists
git ls-remote origin manifests

# Check deploy logs for git errors
strata deploy run -f prod.yaml --verbose 2>&1 | grep -i "git\|push\|branch"

Manifest Has Empty artifacts.content๏ƒ

Cause: Platform artifact wasnโ€™t generated.

Fix: Run strata build run before strata deploy run:

strata build run -f prod.yaml
strata deploy run -f prod.yaml

Export Audit Trail with Manifests๏ƒ

# Export all deployment logs plus associated manifests
strata audit export --output-dir ./audit_export --include-manifests

# Result:
# audit_export/
#   deploy_logs/
#     log_001.json
#     log_002.json
#   manifests/
#     manifest_001.json
#     manifest_002.json

Build Manifests๏ƒ

Build manifests are generated automatically during strata build run and stored in .strata/build/{deployment}/manifest.json. They capture the state before deployment.

When are Build Manifests Created?๏ƒ

strata build run -f deploy.yaml
# Executes: platform builder โ†’ terraform builder โ†’ ansible builder โ†’ helm builder โ†’ sbom builder
# Writes: .strata/build/{deployment}/manifest.json (contains all build artifacts + SBOM reference)

Build Manifest Structure๏ƒ

{
  "apiVersion": "strata.huybrechts.xyz/v1",
  "kind": "deployment-manifest",
  "meta": {
    "name": "prod_deployment",
    "labels": {
      "version": "2.3.0",
      "environment": "production"
    }
  },
  "spec": {
    "deployment_name": "prod_deployment",
    "workspace_name": "prod_workspace",
    "action": "build",
    "status": "success",
    "timestamp": "2024-06-17T10:35:20Z",
    "user": "devops@acme.com",
    "platform_version": "1.2.0",
    "build_duration_seconds": 87,
    
    "artifacts": {
      "platform": {
        "hash": "sha256:abc123def456...",
        "path": ".strata/build/prod_deployment/platform.json",
        "content": { ...full platform.json snapshot... }
      },
      
      "repositories": {
        "xyz-infrastructure": {
          "url": "git@github.com:acme/xyz-infra.git",
          "ref": "v2.3.0",
          "commit": "a1b2c3d4e5f6g7h8..."
        }
      },
      
      "sbom": {
        "path": ".strata/build/prod_deployment/sbom.json",
        "format": "cyclonedx-1.6",
        "sha256": "sha256:xyz789..."
      }
    },
    
    "policy_results": {
      "status": "passed",
      "policies_checked": 12,
      "policies_passed": 12,
      "violations": []
    }
  }
}

Key Differences from Deploy Manifests๏ƒ

Aspect

Build

Deploy

Trigger

strata build run

strata deploy run

Stages

None

Multiple (infrastructure, configure, etc.)

Outputs

SBOM, policy results

Stage outputs, resource IDs, IPs

Errors

Build/validation errors

Provisioner errors

Purpose

Gate before deploying

Record what was deployed

Querying Build Manifests๏ƒ

# List only build manifests (not deployment manifests)
find .strata/build -name "manifest.json" -type f

# Show details of a build
jq '.spec | {timestamp, user, build_duration_seconds, policy_results}' \
  .strata/build/prod_deployment/manifest.json

# Check if build passed all policies
jq '.spec.policy_results.status' .strata/build/prod_deployment/manifest.json

Workflow: Review Build Before Deploying๏ƒ

# 1. Build artifacts
strata build run -f deploy/prod.yaml

# 2. Review the build manifest
strata manifest show .strata/build/prod_deployment/manifest.json

# 3. Check policy results
jq '.spec.policy_results' .strata/build/prod_deployment/manifest.json

# 4. If satisfied, deploy
strata deploy run -f deploy/prod.yaml

Best Practices๏ƒ

  1. Store manifests in version control โ€” Commit local manifests to Git alongside your deployment configs.

  2. Tag important deployments โ€” Use Git tags in the state repo to mark production releases.

  3. Automate archive cleanup โ€” Old manifests accumulate; implement retention policies (e.g., keep last 30 days).

  4. Query manifests regularly โ€” Build alerts/dashboards around manifest status, duration, user, and configuration changes.

  5. Include in change tickets โ€” Reference the manifest commit hash in your change management system (e.g., โ€œChanges applied in manifest commit abc123dโ€).

  6. Review SBOM for vulnerabilities โ€” Extract and scan the SBOM component list for known CVEs after each deployment.


See Also๏ƒ