|
| 1 | +# hardbox — Terraform Provider |
| 2 | + |
| 3 | +The `jackby03/hardbox` Terraform provider applies OS hardening to remote Linux |
| 4 | +hosts as part of your infrastructure-as-code workflow. It installs the hardbox |
| 5 | +binary, runs a compliance profile, and surfaces audit findings in Terraform state. |
| 6 | + |
| 7 | +Supported targets: **AWS EC2**, **GCP Compute Engine**, **Azure VMs**, and any |
| 8 | +SSH-accessible Linux host. |
| 9 | + |
| 10 | +--- |
| 11 | + |
| 12 | +## Installation |
| 13 | + |
| 14 | +Add the provider to your `required_providers` block: |
| 15 | + |
| 16 | +```hcl |
| 17 | +terraform { |
| 18 | + required_providers { |
| 19 | + hardbox = { |
| 20 | + source = "jackby03/hardbox" |
| 21 | + version = "~> 0.3" |
| 22 | + } |
| 23 | + } |
| 24 | +} |
| 25 | +``` |
| 26 | + |
| 27 | +```bash |
| 28 | +terraform init |
| 29 | +``` |
| 30 | + |
| 31 | +--- |
| 32 | + |
| 33 | +## Provider Configuration |
| 34 | + |
| 35 | +```hcl |
| 36 | +provider "hardbox" { |
| 37 | + # Optional: pin the hardbox binary version installed on all managed hosts. |
| 38 | + # Defaults to "latest" if omitted. |
| 39 | + hardbox_version = "v0.3.0" |
| 40 | +} |
| 41 | +``` |
| 42 | + |
| 43 | +| Argument | Type | Default | Description | |
| 44 | +|---|---|---|---| |
| 45 | +| `hardbox_version` | string | `"latest"` | hardbox release tag to install on remote hosts | |
| 46 | + |
| 47 | +--- |
| 48 | + |
| 49 | +## Resource: `hardbox_apply` |
| 50 | + |
| 51 | +Provisions a remote Linux host with hardbox OS hardening. |
| 52 | + |
| 53 | +### What it does |
| 54 | + |
| 55 | +1. Connects to the host over SSH. |
| 56 | +2. Downloads the hardbox binary and verifies its SHA-256 checksum. |
| 57 | +3. Runs `hardbox apply` with the selected compliance profile. |
| 58 | +4. Captures the audit report and surfaces finding counts in state. |
| 59 | +5. On `terraform destroy`, runs `hardbox rollback apply --last`. |
| 60 | + |
| 61 | +### Arguments |
| 62 | + |
| 63 | +#### SSH connection |
| 64 | + |
| 65 | +| Argument | Required | Description | |
| 66 | +|---|---|---| |
| 67 | +| `host` | yes | IP address or hostname of the target | |
| 68 | +| `port` | no | SSH port (default: `22`) | |
| 69 | +| `user` | no | SSH username (default: `root`) | |
| 70 | +| `private_key` | no | PEM-encoded SSH private key | |
| 71 | +| `agent_socket` | no | Path to SSH agent socket (`$SSH_AUTH_SOCK`) | |
| 72 | + |
| 73 | +#### hardbox options |
| 74 | + |
| 75 | +| Argument | Default | Description | |
| 76 | +|---|---|---| |
| 77 | +| `profile` | required | Compliance profile name | |
| 78 | +| `hardbox_version` | provider default | Override version for this resource | |
| 79 | +| `dry_run` | `false` | Preview changes without applying | |
| 80 | +| `rollback_on_failure` | `true` | Rollback automatically on failure | |
| 81 | +| `report_format` | `"json"` | `json`, `html`, `text`, `markdown` | |
| 82 | +| `fail_on_critical` | `true` | Fail apply on critical findings | |
| 83 | +| `fail_on_high` | `true` | Fail apply on high findings | |
| 84 | + |
| 85 | +### Computed attributes |
| 86 | + |
| 87 | +| Attribute | Description | |
| 88 | +|---|---| |
| 89 | +| `id` | `<host>:<profile>@<applied_at>` | |
| 90 | +| `applied_at` | RFC3339 timestamp of last apply | |
| 91 | +| `installed_version` | hardbox version installed on the host | |
| 92 | +| `report_content` | Full audit report (JSON/HTML/text) | |
| 93 | +| `findings` | Map of severity counts: `{critical, high, medium, low, info}` | |
| 94 | + |
| 95 | +--- |
| 96 | + |
| 97 | +## Examples |
| 98 | + |
| 99 | +### AWS EC2 |
| 100 | + |
| 101 | +```hcl |
| 102 | +resource "hardbox_apply" "web" { |
| 103 | + host = aws_instance.web.public_ip |
| 104 | + user = "ubuntu" |
| 105 | + private_key = file("~/.ssh/id_rsa") |
| 106 | +
|
| 107 | + profile = "cloud-aws" |
| 108 | + report_format = "json" |
| 109 | + fail_on_critical = true |
| 110 | + fail_on_high = true |
| 111 | + rollback_on_failure = true |
| 112 | +} |
| 113 | +
|
| 114 | +output "findings" { |
| 115 | + value = hardbox_apply.web.findings |
| 116 | +} |
| 117 | +``` |
| 118 | + |
| 119 | +Full example: [`examples/aws/`](../terraform-provider/examples/aws/) |
| 120 | + |
| 121 | +### GCP Compute Engine |
| 122 | + |
| 123 | +```hcl |
| 124 | +resource "hardbox_apply" "web" { |
| 125 | + host = google_compute_instance.web.network_interface[0].network_ip |
| 126 | + user = "ubuntu" |
| 127 | + private_key = file("~/.ssh/id_rsa") |
| 128 | +
|
| 129 | + profile = "cloud-gcp" |
| 130 | + report_format = "json" |
| 131 | +} |
| 132 | +``` |
| 133 | + |
| 134 | +Full example: [`examples/gcp/`](../terraform-provider/examples/gcp/) |
| 135 | + |
| 136 | +### Azure VM |
| 137 | + |
| 138 | +```hcl |
| 139 | +resource "hardbox_apply" "vm" { |
| 140 | + host = azurerm_network_interface.nic.private_ip_address |
| 141 | + user = "azureuser" |
| 142 | + private_key = file("~/.ssh/id_rsa") |
| 143 | +
|
| 144 | + profile = "cloud-azure" |
| 145 | + report_format = "json" |
| 146 | +} |
| 147 | +``` |
| 148 | + |
| 149 | +Full example: [`examples/azure/`](../terraform-provider/examples/azure/) |
| 150 | + |
| 151 | +### Audit-only (no changes) |
| 152 | + |
| 153 | +```hcl |
| 154 | +resource "hardbox_apply" "audit" { |
| 155 | + host = var.host_ip |
| 156 | + user = "ubuntu" |
| 157 | + private_key = file(var.key_path) |
| 158 | +
|
| 159 | + profile = "cis-level2" |
| 160 | + dry_run = true # --dry-run: no changes applied |
| 161 | +} |
| 162 | +``` |
| 163 | + |
| 164 | +--- |
| 165 | + |
| 166 | +## Profiles |
| 167 | + |
| 168 | +| Profile | Framework | |
| 169 | +|---|---| |
| 170 | +| `cis-level1` | CIS Benchmarks Level 1 | |
| 171 | +| `cis-level2` | CIS Benchmarks Level 2 | |
| 172 | +| `pci-dss` | PCI-DSS v4.0 | |
| 173 | +| `stig` | DISA STIG | |
| 174 | +| `hipaa` | HIPAA Security Rule | |
| 175 | +| `iso27001` | ISO/IEC 27001:2022 | |
| 176 | +| `cloud-aws` | CIS AWS Foundations v2.0 | |
| 177 | +| `cloud-gcp` | CIS GCP Foundations v2.0 | |
| 178 | +| `cloud-azure` | CIS Azure Foundations v2.1 | |
| 179 | +| `production` | hardbox curated | |
| 180 | +| `development` | hardbox curated | |
| 181 | + |
| 182 | +--- |
| 183 | + |
| 184 | +## CI/CD Integration |
| 185 | + |
| 186 | +### GitHub Actions |
| 187 | + |
| 188 | +```yaml |
| 189 | +- name: Terraform apply (with hardbox hardening) |
| 190 | + run: terraform apply -auto-approve |
| 191 | + env: |
| 192 | + TF_VAR_private_key: ${{ secrets.SSH_PRIVATE_KEY }} |
| 193 | +``` |
| 194 | +
|
| 195 | +### GitLab CI |
| 196 | +
|
| 197 | +```yaml |
| 198 | +terraform: |
| 199 | + script: |
| 200 | + - terraform init |
| 201 | + - terraform apply -auto-approve |
| 202 | + variables: |
| 203 | + TF_VAR_private_key: $SSH_PRIVATE_KEY |
| 204 | +``` |
| 205 | +
|
| 206 | +--- |
| 207 | +
|
| 208 | +## Building from source |
| 209 | +
|
| 210 | +```bash |
| 211 | +cd terraform-provider/ |
| 212 | +go build -o terraform-provider-hardbox . |
| 213 | + |
| 214 | +# Install locally for testing |
| 215 | +mkdir -p ~/.terraform.d/plugins/registry.terraform.io/jackby03/hardbox/0.3.0/linux_amd64 |
| 216 | +cp terraform-provider-hardbox \ |
| 217 | + ~/.terraform.d/plugins/registry.terraform.io/jackby03/hardbox/0.3.0/linux_amd64/ |
| 218 | +``` |
| 219 | + |
| 220 | +--- |
| 221 | + |
| 222 | +## Publishing to Terraform Registry |
| 223 | + |
| 224 | +The provider is published to the [Terraform Registry](https://registry.terraform.io/providers/jackby03/hardbox) |
| 225 | +via GitHub Actions on release tag push. The registry indexes `terraform-provider/` |
| 226 | +as the provider source directory. |
0 commit comments