Skip to content
Notifications
Clear all

Guide: How we do integration testing for our OpenClaw modules using localstack.

2 Posts
2 Users
0 Reactions
2 Views
(@infra_auditor_nina)
Reputable Member
Joined: 4 months ago
Posts: 159
Topic starter   [#7573]

Another day, another "we've achieved full CI/CD" standup. Then you push a Terraform change and it all goes sideways because, surprise, what works in your `dev` account explodes in production due to a subtle S3 or SQS policy. Mocking providers only gets you so far. So we actually test our OpenClaw security modules *against* real AWS services. Locally. Without a credit card.

The trick is LocalStack, but not just for spinning up a dummy S3 bucket. We treat it as a full, ephemeral AWS partition for our integration tests. Our modules (think: auto-remediation lambdas, security hub enrichers) get deployed via Terraform *into* LocalStack, then invoked with real events. We validate they behave as intended and, crucially, leave the audit trail we expect.

Here's the core of our `pytest` fixture that sets up the isolated environment:

```python
@pytest.fixture(scope="module")
def localstack_infra():
"""Terraform apply to LocalStack, yield outputs, destroy after."""
# Apply minimal module TF config (pointed at localstack endpoints)
subprocess.run(["terraform", "init"], check=True, cwd=TEST_MODULE_PATH)
apply_result = subprocess.run(
["terraform", "apply", "-auto-approve", "-var", "localstack_endpoint= http://localhost:456 6"],
capture_output=True,
text=True,
cwd=TEST_MODULE_PATH
)
# Parse outputs (e.g., lambda_arn, queue_url)
outputs = json.loads(subprocess.run(["terraform", "output", "-json"], capture_output=True, text=True, cwd=TEST_MODULE_PATH).stdout)
yield outputs
# Teardown
subprocess.run(["terraform", "destroy", "-auto-approve"], check=True, cwd=TEST_MODULE_PATH)
```

Key points we've learned the hard way:
* **State Isolation:** Every test run gets a unique `tfstate` file scoped to the test session. No collisions.
* **Service Coverage:** LocalStack Pro for anything beyond basic services. Their Lambda implementation has quirks, but it's good enough for our contract tests.
* **Speed:** It's still slower than unit tests, so we only run this suite on PRs, not every commit.
* **What it catches:** IAM policy misalignments, service principal typos, event payload mismatches between EventBridge and our Lambda. The stuff that would cause a Sev-3 at 2 AM.

Is it perfect? No. You still need canary deployments in real AWS. But it's stopped us from shipping at least three critical logic flaws that mocked unit tests happily passed. Because the cloud providers' APIs *are* the real interface. Might as well test against them.

- Nina


- Nina


   
Quote
(@infra_ops_learner)
Estimable Member
Joined: 3 months ago
Posts: 81
 

This is super cool, thanks for sharing! I've only used LocalStack for simple mocking, so the idea of a full terraform apply into it is new to me.

How do you handle IAM roles and policies in LocalStack? Do you create them with terraform too, or does your test fixture just use a permissive "admin" role for the test run?


CloudNewbie


   
ReplyQuote