Reproducible embedded CI with VectorCAST, Jenkins and Pulumi
embeddedpulumici-cd

Reproducible embedded CI with VectorCAST, Jenkins and Pulumi

UUnknown
2026-02-20
11 min read
Advertisement

Step-by-step guide to provisioning reproducible testbeds with Pulumi, running VectorCAST + RocqStat in Jenkins, and tearing down resources automatically.

Ship reliable embedded software faster: reproducible CI for VectorCAST + RocqStat using Pulumi and Jenkins

Pain point: slow, brittle embedded CI pipelines with manual testbed provisioning and expensive cloud surprises. This guide shows how to provision reproducible testbeds as code with Pulumi, run VectorCAST and RocqStat analysis from Jenkins, collect artifacts, and tear everything down automatically.

Why this matters in 2026

Embedded systems teams face mounting verification pressure: real-time constraints, safety standards, and increasingly complex toolchains. In January 2026, Vector Informatik acquired StatInf’s RocqStat technology, signaling broader industry consolidation and tighter integration between WCET (worst-case execution time) analysis and software testing workflows.

Vector's move points to a single unified verification path: test, timing analysis, and verification under one roof.

That means teams need reproducible, auditable, and automatable testbeds that run VectorCAST and RocqStat analyses reliably in CI. Infrastructure as code (IaC) paired with ephemeral testbed patterns is the practical path forward.

What you’ll get from this article

  • Architecture and pattern choices for reproducible embedded CI
  • Step-by-step repo layout and Pulumi examples (TypeScript) to spin up testbeds
  • Jenkins pipeline snippet that drives Pulumi, runs VectorCAST/RocqStat, stores artifacts, and destroys resources
  • Security, cost-control, and operational best practices for 2026

High-level pattern: ephemeral testbeds as code

Choose ephemeral testbeds per CI job when isolation and reproducibility are critical (safety certification, WCET runs). The pattern:

  1. Jenkins job invokes Pulumi to create a small testbed (network, VM/container host, artifact store, optional license server access).
  2. Pulumi returns connection details (host, SSH key, artifact URL).
  3. Jenkins runs build & VectorCAST/RocqStat analysis on the provisioned host (via SSH, Docker, or remote agent).
  4. Artifacts and logs are uploaded to a central artifact store (S3/GCS/Artifactory).
  5. Jenkins triggers Pulumi destroy to tear down resources.

Why Pulumi?

Pulumi lets you express infrastructure in real programming languages (TypeScript, Python). For embedded CI you get:

  • Reproducible, testable IaC modules
  • Fine-grained runtime logic (create conditional license proxies, snapshot VMs)
  • Secrets handling via Pulumi Config + secret providers

Quick architecture example (AWS-centric, but cloud-agnostic)

The examples below use AWS resources, but the same Pulumi code patterns apply for Azure, GCP, or on-prem VMware/Libvirt with provider switches.

  • VPC with subnet/security group
  • EC2 instance (or ECS Fargate task) running Docker Compose image: vectorcast-cli + rocqstat CLI
  • S3 bucket for artifacts and logs
  • IAM role for instance to push artifacts to S3
  • Optional NAT / Internet access or VPC endpoints for security

Keep a single repo that contains Pulumi stacks, Jenkins pipelines, and sample Docker images. Example layout:

<repo-root>
  ├─ pulumi/
  │  ├─ index.ts            # Pulumi program (TypeScript)
  │  ├─ Pulumi.dev.yaml     # stack config for dev
  │  └─ Pulumi.prod.yaml
  ├─ jenkins/
  │  └─ Jenkinsfile         # Pipeline calling Pulumi + RUN steps
  ├─ docker/
  │  └─ vectorcast-ci.Dockerfile
  ├─ docs/
  │  └─ run-locally.md
  └─ README.md
  

Prerequisites

  • Pulumi CLI vlatest (pin to a specific release in CI, see notes)
  • Node 20+ for TypeScript Pulumi program
  • AWS credentials with least privilege for the resources you create
  • Jenkins controller (can run Pulumi CLI inside a Docker agent)
  • VectorCAST and RocqStat licenses—or a license proxy reachable from the testbed

Pulumi TypeScript example: create a minimal testbed

The snippet below is a focused example — creating a VPC, EC2 instance with a userdata script that pulls and runs a Docker image containing VectorCAST CLI and RocqStat CLI. Save this as pulumi/index.ts in the repo.

// pulumi/index.ts (TypeScript)
import * as aws from "@pulumi/aws";
import * as pulumi from "@pulumi/pulumi";

const config = new pulumi.Config();
const instanceType = config.get("instanceType") || "t3.medium";
const keyName = config.require("sshKeyName");
const ami = aws.getAmi({ mostRecent: true, owners: ["amazon"] , filters: [{ name: "name", values: ["amzn2-ami-hvm-*-x86_64-gp2"] }] });

// VPC + subnet (use default VPC in small example for brevity)
const sg = new aws.ec2.SecurityGroup("vc-sg", {
    description: "Allow SSH and necessary egress",
    ingress: [ { protocol: "tcp", fromPort: 22, toPort: 22, cidrBlocks: ["0.0.0.0/0"] } ],
    egress: [ { protocol: "-1", fromPort: 0, toPort: 0, cidrBlocks: ["0.0.0.0/0"] } ],
});

// IAM role for S3 upload
const role = new aws.iam.Role("vc-role", {
    assumeRolePolicy: aws.iam.assumeRolePolicyForPrincipal({ Service: "ec2.amazonaws.com" }),
});
new aws.iam.RolePolicyAttachment("vc-s3-attach", {
    role: role.name,
    policyArn: aws.iam.ManagedPolicies.AmazonS3FullAccess, // tighten in prod
});
const profile = new aws.iam.InstanceProfile("vc-profile", { role: role });

const userData = `#!/bin/bash
sudo yum update -y
# install docker
amazon-linux-extras install -y docker
service docker start
usermod -a -G docker ec2-user
# Fetch container image (private registry auth would go here)
docker run --rm -d --name vc-ci -v /tmp/artifacts:/artifacts myorg/vectorcast-rocqstat-cli:2026-01
`;

const server = new aws.ec2.Instance("vc-instance", {
    ami: ami.then(a => a.id),
    instanceType: instanceType,
    keyName: keyName,
    vpcSecurityGroupIds: [sg.id],
    iamInstanceProfile: profile.name,
    userData: userData,
    tags: { Name: "vectorcast-testbed" },
});

export const instancePublicIp = server.publicIp;
export const instancePublicHost = server.publicDns;

Key points:

  • Keep instance boot scripts minimal. Use container images for VectorCAST and RocqStat CLI to ensure repeatability.
  • Limit IAM permissions — in production replace AmazonS3FullAccess with a scoped policy to your artifacts prefix.

Sample Docker image: vectorcast + rocqstat CLI

Build a small headless image containing the VectorCAST CLI and RocqStat CLI wrappers. Push to ECR/Container Registry accessible by your testbed.

// docker/vectorcast-ci.Dockerfile
FROM ubuntu:22.04
# Install deps, copy VectorCAST CLI and RocqStat CLI binaries (packaged by your org)
COPY vectorcast-cli /usr/local/bin/vectorcast
COPY rocqstat /usr/local/bin/rocqstat
RUN chmod +x /usr/local/bin/*
# Entrypoint waits for commands from CI controller (simple example)
ENTRYPOINT ["/bin/bash"]

Jenkins pipeline: orchestrate Pulumi, run tests, collect artifacts, destroy

Place this Jenkinsfile under jenkins/Jenkinsfile. It demonstrates the full loop: up → run → collect → destroy.

// jenkins/Jenkinsfile
pipeline {
  agent { docker { image 'pulumi/pulumi:latest' } }
  environment {
    PULUMI_ACCESS_TOKEN = credentials('pulumi-token')
    AWS_ACCESS_KEY_ID = credentials('aws-id')
    AWS_SECRET_ACCESS_KEY = credentials('aws-secret')
  }
  stages {
    stage('Pulumi up') {
      steps {
        sh 'cd pulumi && npm ci && pulumi stack select dev || pulumi stack init dev'
        sh 'cd pulumi && pulumi up --yes --skip-preview'
        script {
          instance = sh(script: "cd pulumi && node -e \"console.log(require('./index.js').instancePublicIp)\"", returnStdout:true).trim()
          env.INSTANCE_IP = instance
        }
      }
    }
    stage('Run VectorCAST & RocqStat') {
      steps {
        // SSH and run inside container. For robust usage use an SSH agent and key credential
        sh "ssh -o StrictHostKeyChecking=no -i ~/.ssh/id_rsa ec2-user@${env.INSTANCE_IP} \"docker exec vc-ci /usr/local/bin/vectorcast --run /workspace/project && docker exec vc-ci /usr/local/bin/rocqstat --analyze /workspace/project --output /artifacts/rocq.json\""
      }
    }
    stage('Collect artifacts') {
      steps {
        sh "ssh -i ~/.ssh/id_rsa ec2-user@${env.INSTANCE_IP} \"tar -czf /tmp/artifacts.tgz -C /tmp/artifacts .\""
        sh "scp -i ~/.ssh/id_rsa ec2-user@${env.INSTANCE_IP}:/tmp/artifacts.tgz ./artifacts.tgz"
        sh "aws s3 cp artifacts.tgz s3://my-vc-artifacts/${env.BUILD_ID}/artifacts.tgz"
      }
    }
    stage('Pulumi destroy') {
      steps {
        sh 'cd pulumi && pulumi destroy --yes'
      }
    }
  }
}

Notes:

  • Use Pulumi Automation API or CLI in CI agents—both are valid. Automation API offers richer programmatic control and better status reporting.
  • Wrap SSH usage in retry logic to handle EC2 boot delays.
  • In regulated environments, record Pulumi outputs and approvals for traceability.

RocqStat integration and postprocessing

With Vector's acquisition of RocqStat (Jan 2026), expect tighter integration where RocqStat data becomes a first-class VectorCAST artifact. For the meantime, run RocqStat CLI after VectorCAST test execution:

  1. Export binary and execution traces from VectorCAST (timing hooks) into the container’s workspace.
  2. Invoke rocqstat to compute WCET and produce JSON/XML outputs.
  3. Upload both test results and WCET reports to artifacts store, and attach to the Jenkins build (for traceability).

Example run command (inside your container):

vectorcast --project myproj --run && rocqstat --input ./myproj/traces --config wcet.cfg --output /artifacts/wcet.json

Reproducibility techniques (practical checklist)

  • Pin container images with digest (avoid :latest). This ensures binary-level reproducibility of VectorCAST + RocqStat environment.
  • Lock Pulumi versions in your build image; record provider plugin versions (pulumi plugin ls) as build artifacts.
  • Use Pulumi config files checked into the repo for non-secrets and secret providers (AWS KMS, Azure KeyVault) for secrets.
  • Record VM image/AMI IDs (or use immutable images baked with Packer) so boots are deterministic.
  • Version your VectorCAST and RocqStat tools and store installer artifacts in a registered artifact repository.

Cost control and speed optimizations

Ephemeral testbeds cost money. Use these patterns to reduce spend without sacrificing isolation:

  • Spot instances for non-critical runs (with checkpointed work).
  • Use smaller compute and run parallelization smartly: run unit tests in parallel on small workers; run full WCET runs on larger instance types with reserved scheduling.
  • Snapshot golden testbed images after initial setup and reuse as AMIs to shave minutes off provisioning.
  • Set automatic destroy and safety nets: Pulumi destroy on job completion and a cloud-side scheduled cleanup for orphaned resources older than X hours.

Security, licensing, and compliance considerations

  • VectorCAST/RocqStat are licensed products. Do not bake licenses into images. Use a license server reachable via secured VPC peering or VPN; configure ephemeral testbeds to register with the license proxy.
  • Use IAM roles for workloads — never hardcode cloud credentials in images or scripts.
  • Audit Pulumi state (Pulumi Cloud or backend) and restrict stack access with RBAC.
  • Record testbed inputs (sources, configs, tool versions) for reproducibility and certification evidence.

Advanced strategies for teams

1) Shared golden workers

For speed, maintain a small pool of pre-warmed workers (AMI or container) per branch. Use Pulumi to scale the pool based on CI queue depth.

2) Pulumi automation API for integrated pipelines

The Pulumi Automation API embeds Pulumi into a control plane service. Use it to implement per-PR testbed orchestration with richer error handling than raw CLI. It helps when you need to programmatically create/destroy stacks from your Jenkins master or a dedicated orchestration service.

3) Canary + artifact signing

When a test run passes, sign artifacts and store signatures with results. This builds an audit trail for safety-critical releases.

Troubleshooting common issues

  • EC2 boot fails: check userData cloud-init logs (/var/log/cloud-init-output.log) and ensure IAM profile attached.
  • Container pull fails: confirm registry auth for instance; use ECR credentials helper or attach an instance policy for ECR access.
  • Pulumi missing providers: pin provider plugin versions in CI image.
  • Licensing errors: ensure license server reachable from VPC; validate license tokens in a preflight job.

Example: Full end-to-end run checklist (quickplay)

  1. Check out repo; ensure Pulumi and Node pinned in CI image.
  2. Configure Pulumi stack with sshKeyName, instanceType, and artifact bucket.
  3. Build/push vectorcast-rocqstat image to container registry.
  4. Trigger Jenkins job — it should create the testbed, run analysis, upload artifacts, and destroy the testbed.
  5. Verify artifacts in S3 and logs in Jenkins. Collect WCET JSON and include in release notes if needed.
  • Tool consolidation: With Vector integrating RocqStat, expect unified workflows. Plan to replace brittle ad-hoc scripts with integrated VectorCAST-RocqStat steps in CI.
  • Policy-as-code: Embed security and cost guardrails in Pulumi stacks (i.e., deny public S3 buckets, enforce tagging).
  • Cloud-native verification: More teams run WCET analysis in containers — make your images trusted and reproducible.

Actionable takeaways

  • Start small: create a single reproducible Pulumi stack that boots a containerized VectorCAST+RocqStat runner.
  • Automate the full lifecycle in Jenkins: pulumi up → run → publish artifacts → pulumi destroy.
  • Pin images, Pulumi versions, and provider plugins to ensure repeatable runs for certification needs.
  • Use secrets and license proxies; never bake keys into images.

Further reading and references

  • Vector Informatik acquisition news (Jan 2026) on RocqStat — this highlights integration momentum for timing analysis.
  • Pulumi docs: Automation API and provider plugin management
  • VectorCAST / RocqStat product guides — follow vendor guidance for headless CLI usage and licensing

Wrap-up and next steps

Reproducible embedded CI is achievable with a pragmatic mix of Pulumi IaC and Jenkins orchestration. The practical pattern is ephemeral, immutable testbeds that run VectorCAST and RocqStat in containerized, versioned environments. This reduces flakiness, improves traceability for safety evidence, and controls cloud spend by tearing down resources automatically.

Ready to try it? Clone the starter repo (linked in this article's companion repo), run the Pulumi dev stack locally, and iterate toward integrating this flow into your Jenkins pipeline. Start with a single PR job to validate environment reproducibility and licensing.

Call to action

Get the ready-to-run example repository, Pulumi stack, and Jenkins pipeline templates from our companion repo. If you want help adapting this to your cloud or on-prem env, reach out for a hands-on workshop to convert your VectorCAST/RocqStat runs into fully reproducible IaC-driven pipelines.

Advertisement

Related Topics

#embedded#pulumi#ci-cd
U

Unknown

Contributor

Senior editor and content strategist. Writing about technology, design, and the future of digital media. Follow along for deep dives into the industry's moving parts.

Advertisement
2026-02-21T19:55:07.088Z