The Philosophical Developer -- Chapter 30: Deploy and Verify
2026-07-21 · 4 min read

Unit tests with mocks validate the code. They do not validate the infrastructure. A mock returns whatever you tell it to return. It will never catch a misconfigured resource, a misaligned IAM policy, or a subnet that overlaps with another subnet.
For that, you need to deploy against a real API.
In the OpenTofu arc, we used Floci, a lightweight AWS emulator that runs in a Docker container. It implements the AWS API surface at the wire level, enough to create resources, read them back, and verify the outputs. The same approach works for Pulumi.
I sat down with OrsonRius and we wrote three scripts. One to start Floci. One to deploy the stack. One to run the full integration lifecycle.
The integration test scripts
The scripts live in infrastructure/pulumi/scripts/. Each one is a shell script that runs the corresponding phase of the integration lifecycle.
The up.sh script starts Floci in a Docker container and waits for it to be ready.
#!/usr/bin/env bash
set -euo pipefail
docker run --rm -d --name floci -p 4566:4566 floci/floci:latest
for i in $(seq 1 30); do
if curl -s http://localhost:4566/_localstack/health > /dev/null 2>&1; then
echo "Floci ready."
break
fi
sleep 1
done
The deploy.sh script initializes the Pulumi stack, configures the Floci endpoints, runs a preview, and deploys the infrastructure.
cd infrastructure/pulumi
pulumi stack select dev 2>/dev/null || pulumi stack init dev
pulumi config set aws:accessKey test
pulumi config set aws:secretKey test
pulumi config set aws:skipCredentialsValidation "true"
pulumi config set aws:skipMetadataApiCheck "true"
pulumi config set aws:skipRequestingAccountId "true"
pulumi preview
pulumi up --yes
pulumi stack output
The full lifecycle test
The integration-test.sh script runs the complete lifecycle. Start Floci, deploy the stack, verify the outputs, destroy the stack, stop Floci. It is the integration equivalent of the unit test suite.
# Step 1: Start Floci
docker run --rm -d --name floci -p 4566:4566 floci/floci:latest
# Step 2: Deploy
pulumi up --yes --skip-preview
# Step 3: Verify outputs
OUTPUTS=$(pulumi stack output --json)
echo "$OUTPUTS" | grep -q "bucketName" || exit 1
echo "$OUTPUTS" | grep -q "vpcId" || exit 1
echo "$OUTPUTS" | grep -q "roleName" || exit 1
echo "$OUTPUTS" | grep -q "tableName" || exit 1
# Step 4: Cleanup
pulumi destroy --yes
docker stop floci
The script checks for seven outputs, one for each module. If any output is missing, the script exits with a non-zero code. The trap handler ensures cleanup happens even if a step fails.
The Floci configuration
Floci emulates the AWS API on localhost port 4566. The Pulumi stack configuration tells the AWS provider to use the Floci endpoints instead of the real AWS API.
The Pulumi.dev.yaml file configures the environment:
config:
aws:region: us-east-1
aws:s3UsePathStyle: "true"
aws:skipCredentialsValidation: "true"
aws:skipMetadataApiCheck: "true"
aws:skipRequestingAccountId: "true"
The credentials are test credentials. They are not real AWS credentials. Floci accepts any access key and secret key and returns success for any API call that it implements.
What the integration test validates
The integration test validates three things that unit tests cannot.
First, that the resources are created with the correct names and properties. The Floci API returns real identifiers for the resources it creates. The test checks that the outputs match the expected values.
Second, that the resource dependencies are correct. The ECS service references the cluster by name. The IAM policy is attached to the role. The subnet is a child of the VPC. If any dependency is misconfigured, the deployment will fail.
Third, that the stack output is consistent. Each module exports the expected outputs. The test checks that all seven outputs are present and non-empty.
The gap
Floci does not implement the full AWS API surface. It supports S3, DynamoDB, IAM, and EC2 at a basic level. It does not support ECS, ECR, or Kubernetes. The integration test for the full stack will skip the ECS, ECR, and K8s modules until Floci adds support for those services.
The unit tests cover all seven modules. The integration test covers the four that Floci supports. The gap is acceptable because the unit tests validate the code structure, and the integration test validates the deployment lifecycle.
Repos:
- github.com/dark5un/local-cloud – infrastructure/pulumi/scripts/
LinkedIn:
Here I geek out with my young Padawan, OrsonRius.