Skip to content
Notifications
Clear all

Check out my Terraform module to deploy Aqua's helm chart with custom configs.

3 Posts
3 Users
0 Reactions
2 Views
(@devops_not_grunt)
Reputable Member
Joined: 5 months ago
Posts: 159
Topic starter   [#19347]

So the official Aqua docs, and half the blog posts out there, tell you to just `helm install` with a values.yaml the size of a novel. Ever tried to manage that mess across three environments with slight deviations? Yeah, it's a festival of copy-paste errors waiting for a midnight page.

I got tired of the "it's just Helm" mantra after an incident where a staging config accidentally disabled image scanning in prod because someone missed a nested conditional. The whole point of IaC is to be *intelligent* about repetition, not to replicate it.

So I built a Terraform module that actually treats the Helm chart as a library. You define your *intent* (e.g., "scan on push," "enforce these policies"), and it builds the proper values structure. It uses Terraform's constructs for merging and overriding, so you have a sane base, an environment overlay, and optional per-cluster tweaks that can't silently break core security.

Here's the core idea. Instead of a monolithic file, you feed it structured objects:

```hcl
module "aqua_enterprise" {
source = "github.com/.../aqua-helm-terraform"

environment = "production"

scanner = {
replicas = 2
resources = local.large_resources
enable_fargate = false
}

server = {
audit_logs_enabled = true
ssl_certificate = var.aqua_cert
}

# This is the key: policies are a map, easy to diff in PRs
image_assurance_policies = {
"block_critical_cve" = {
enabled = true
only_fixed = false
severity = ["critical", "high"]
fail_on_unfixed = true
}
}
}
```

The module generates the complex, nested values.yaml Helm expects. It also handles the fun stuff like managing the dependency on a Postgres module or secret creation for database passwords, which the vanilla Helm approach just assumes you've done magically beforehand.

Is it more upfront work? Sure. But you now have a reproducible setup where a change to a policy is a code review, not a frantic edit to a YAML labyrinth. And you can finally answer "what's different in prod?" with `terraform plan`. Try that with your 800-line values file.

It's not perfect—Helm's templating and Terraform's declarative model still fight sometimes—but it beats the "hope and pray" school of security configuration. The repo's got examples for deploying on EKS with Fargate for the scanners, because why would we make life simple?



   
Quote
(@crm_hopper)
Estimable Member
Joined: 4 months ago
Posts: 142
 

> "define your intent (e.g., 'scan on push')"

Sure, because wrapping one abstraction in another is definitely the path to less complexity. Now instead of debugging a Helm values file, you get to debug a Terraform module that generates a Helm values file, nested in a plan that you can't easily diff against the actual cluster state. But hey, at least the gitops purists will sleep better.

I've seen this pattern three times now in different orgs. Someone builds a "smart" wrapper, the team loves it for six months, then the wrapper has a bug nobody can fix because the original author left, and they end up pinning modules to a dodgy fork. The real fix is not a better abstraction. It's a better review process and a hard rule that values.yaml lives in version control per environment, with a pre-merge diff check that flags unexpected changes. But that's boring, right?


CRM is a necessary evil


   
ReplyQuote
(@devops_journeyman)
Trusted Member
Joined: 3 months ago
Posts: 61
 

> because someone missed a nested conditional

That's the real pain point, exactly. I've been down that road. A module that enforces a clear contract for security-critical settings sounds like a solid step up from hoping someone spots a YAML indentation error.

My question would be about drift. If the upstream Helm chart adds a new required value in a major version bump, how does your module handle it? Do you expose a raw values passthrough as an escape hatch, or do you have to update the module first? I've built similar wrappers and found that escape valve to be crucial for adoption when you can't block on an internal module update.



   
ReplyQuote