Skip to content

Commit bf3564a

Browse files
committed
add terraform integration test
1 parent 993382a commit bf3564a

File tree

8 files changed

+480
-0
lines changed

8 files changed

+480
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ result*
44

55
# terraform
66
.terraform.lock.hcl
7+
terraform/tests/hcloud/modules/ssh-key/test_key
8+
terraform/tests/hcloud/modules/ssh-key/test_key.pub

terraform/flake-module.nix

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,13 @@
1+
{ inputs, ... }:
12
{
3+
flake.nixosConfigurations.terraform-test = inputs.nixpkgs.lib.nixosSystem {
4+
system = "x86_64-linux";
5+
modules = [
6+
../tests/modules/system-to-install.nix
7+
inputs.disko.nixosModules.disko
8+
];
9+
};
10+
211
perSystem = { pkgs, ... }: {
312
devShells.terraform = pkgs.mkShell {
413
buildInputs = with pkgs; [

terraform/tests/README.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# NixOS Anywhere Terraform Tests
2+
3+
This directory contains tests for the `nixos-anywhere` Terraform modules using
4+
OpenTofu's built-in testing framework.
5+
6+
## Test Structure
7+
8+
```
9+
terraform/tests/
10+
├── main.tf # Core configuration for validation tests
11+
├── nixos-anywhere.tftest.hcl # Basic validation tests (no external deps)
12+
├── nix-build-special-args.tftest.hcl # Nix build module tests with special_args
13+
├── hcloud-deployment.tftest.hcl # Hetzner Cloud integration tests
14+
├── hcloud/ # Hetzner Cloud deployment configuration
15+
├── main.tf
16+
```
17+
18+
### For Hetzner Cloud Tests (Optional)
19+
20+
- Hetzner Cloud account with API token
21+
22+
## Running Tests
23+
24+
### Basic Validation Tests (No External Dependencies)
25+
26+
```bash
27+
# Enter development environment
28+
nix develop .#terraform
29+
30+
# Initialize and run validation tests
31+
cd terraform/tests
32+
tofu init
33+
tofu test
34+
35+
# Run Specific Test File
36+
tofu test -filter=nixos-anywhere.tftest.hcl
37+
```
38+
39+
**Current Status:** Tests available for nixos-anywhere module and nix-build
40+
module
41+
42+
### Hetzner Cloud Integration Tests
43+
44+
```bash
45+
# Set your Hetzner Cloud token
46+
export TF_VAR_hcloud_token="your-64-character-hcloud-token"
47+
48+
# Run Hetzner Cloud tests
49+
tofu test -filter hcloud-deployment.tftest.hcl
50+
```
51+
52+
**Note:** These tests will fail if no valid token is provided.
53+
54+
## Test Categories
55+
56+
### 1. Validation Tests (`nixos-anywhere.tftest.hcl`)
57+
58+
- **Purpose:** Validate configuration structure and variables
59+
- **Dependencies:** None (nixos-anywhere module only)
60+
- **Duration:** 30-60 seconds
61+
- **Cost:** Free
62+
63+
### 2. Nix Build Special Args Tests (`nix-build-special-args.tftest.hcl`)
64+
65+
- **Purpose:** Test nix-build module with special_args functionality
66+
- **Dependencies:** None (nix-build module only)
67+
- **Duration:** 30-60 seconds
68+
- **Cost:** Free
69+
70+
### 3. Hetzner Cloud Tests (`hcloud-deployment.tftest.hcl`)
71+
72+
- **Purpose:** Test complete deployment workflow
73+
- **Dependencies:** Valid Hetzner Cloud token
74+
- **Duration:** 5 minutes (apply tests)
75+
- **Cost:** ~€ 0.006 per hour
76+
77+
## Usage Examples
78+
79+
### Environment Variables
80+
81+
```bash
82+
export TF_VAR_hcloud_token="your-token"
83+
export TF_VAR_test_name_prefix="my-test"
84+
```
85+
86+
### Variable File (Optional)
87+
88+
Create `terraform.tfvars`:
89+
90+
```hcl
91+
hcloud_token = "your-token-here"
92+
test_name_prefix = "tftest-nixos-anywhere"
93+
```
94+
95+
## Cleanup
96+
97+
OpenTofu test automatically cleans up resources. Manual cleanup if needed:
98+
99+
```bash
100+
# List test resources
101+
hcloud server list | grep tftest-nixos-anywhere
102+
hcloud ssh-key list | grep tftest-nixos-anywhere
103+
104+
# Force cleanup
105+
hcloud server delete <server-id>
106+
hcloud ssh-key delete <key-id>
107+
```
108+
109+
## Development
110+
111+
### Test Best Practices
112+
113+
- Use `command = plan` for validation tests
114+
- Use `command = apply` sparingly for integration tests
115+
- Include proper assertions with clear error messages
116+
- Make tests conditional based on available credentials
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Terraform Test Configuration for nixos-anywhere Hetzner Cloud deployment
2+
# Run with: tofu test -var="hcloud_token=your-token-here"
3+
# These tests require a valid Hetzner Cloud API token
4+
5+
variables {
6+
test_name_prefix = "tftest-nixos-anywhere"
7+
}
8+
9+
run "test_hcloud_deployment_apply" {
10+
command = apply
11+
12+
module {
13+
source = "./hcloud"
14+
}
15+
16+
variables {
17+
nixos_system_attr = "github:nix-community/nixos-anywhere-examples#nixosConfigurations.hetzner-cloud.config.system.build.toplevel"
18+
nixos_partitioner_attr = "github:nix-community/nixos-anywhere-examples#nixosConfigurations.hetzner-cloud.config.system.build.diskoNoDeps"
19+
debug_logging = true
20+
}
21+
22+
assert {
23+
condition = output.nixos_anywhere_result != null
24+
error_message = "nixos-anywhere deployment should produce a result"
25+
}
26+
}

terraform/tests/hcloud/main.tf

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
terraform {
2+
required_providers {
3+
hcloud = {
4+
source = "hetznercloud/hcloud"
5+
version = "~> 1.45"
6+
}
7+
tls = {
8+
source = "hashicorp/tls"
9+
version = "~> 4.0"
10+
}
11+
local = {
12+
source = "hashicorp/local"
13+
version = "~> 2.4"
14+
}
15+
}
16+
}
17+
18+
provider "hcloud" {
19+
token = var.hcloud_token
20+
}
21+
22+
variable "hcloud_token" {
23+
description = "Hetzner Cloud API token (64 characters)"
24+
type = string
25+
sensitive = true
26+
}
27+
28+
variable "test_name_prefix" {
29+
description = "Prefix for test resource names"
30+
type = string
31+
default = "tftest-nixos-anywhere"
32+
}
33+
34+
variable "nixos_system_attr" {
35+
description = "NixOS system attribute to deploy"
36+
type = string
37+
}
38+
39+
variable "nixos_partitioner_attr" {
40+
description = "NixOS partitioner attribute"
41+
type = string
42+
}
43+
44+
45+
variable "debug_logging" {
46+
description = "Enable debug logging"
47+
type = bool
48+
default = false
49+
}
50+
51+
# Generate SSH key pair
52+
resource "tls_private_key" "test_key" {
53+
algorithm = "ED25519"
54+
}
55+
56+
# Save private key to file
57+
resource "local_file" "private_key" {
58+
content = tls_private_key.test_key.private_key_openssh
59+
filename = "${path.root}/test_key"
60+
file_permission = "0600"
61+
}
62+
63+
# Save public key to file
64+
resource "local_file" "public_key" {
65+
content = tls_private_key.test_key.public_key_openssh
66+
filename = "${path.root}/test_key.pub"
67+
}
68+
69+
# Create Hetzner Cloud SSH key
70+
resource "hcloud_ssh_key" "test_key" {
71+
name = "${var.test_name_prefix}-deployment-key"
72+
public_key = tls_private_key.test_key.public_key_openssh
73+
}
74+
75+
# Create test server
76+
resource "hcloud_server" "test_server" {
77+
name = "${var.test_name_prefix}-server"
78+
image = "ubuntu-22.04"
79+
server_type = "cx22"
80+
location = "nbg1"
81+
ssh_keys = [hcloud_ssh_key.test_key.id]
82+
83+
labels = {
84+
purpose = "nixos-anywhere-test"
85+
test_run = replace(replace(replace(timestamp(), ":", "-"), "T", "-"), "Z", "")
86+
}
87+
}
88+
89+
# nixos-anywhere all-in-one module
90+
module "nixos_anywhere" {
91+
source = "../../all-in-one"
92+
93+
nixos_system_attr = var.nixos_system_attr
94+
nixos_partitioner_attr = var.nixos_partitioner_attr
95+
target_host = hcloud_server.test_server.ipv4_address
96+
target_port = 22
97+
target_user = "root"
98+
debug_logging = var.debug_logging
99+
deployment_ssh_key = tls_private_key.test_key.private_key_openssh
100+
install_ssh_key = tls_private_key.test_key.private_key_openssh
101+
102+
special_args = {
103+
extraPublicKeys = [tls_private_key.test_key.public_key_openssh]
104+
}
105+
}
106+
107+
output "nixos_anywhere_result" {
108+
description = "nixos-anywhere module result"
109+
value = module.nixos_anywhere.result
110+
}

terraform/tests/main.tf

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
terraform {
2+
required_providers {
3+
external = {
4+
source = "hashicorp/external"
5+
version = "~> 2.3"
6+
}
7+
null = {
8+
source = "hashicorp/null"
9+
version = "~> 3.2"
10+
}
11+
}
12+
}
13+
14+
variable "nixos_system_attr" {
15+
description = "NixOS system attribute to deploy"
16+
type = string
17+
default = ""
18+
}
19+
20+
variable "nixos_partitioner_attr" {
21+
description = "NixOS partitioner attribute"
22+
type = string
23+
default = ""
24+
}
25+
26+
variable "target_host" {
27+
description = "Target host for deployment"
28+
type = string
29+
default = "test.example.com"
30+
}
31+
32+
variable "target_port" {
33+
description = "Target SSH port"
34+
type = number
35+
default = 22
36+
}
37+
38+
variable "target_user" {
39+
description = "Target SSH user"
40+
type = string
41+
default = "root"
42+
}
43+
44+
variable "debug_logging" {
45+
description = "Enable debug logging"
46+
type = bool
47+
default = false
48+
}
49+
50+
variable "phases" {
51+
description = "Deployment phases to run"
52+
type = set(string)
53+
default = ["kexec", "disko", "install"]
54+
}
55+
56+
variable "build_on_remote" {
57+
description = "Build on remote machine"
58+
type = bool
59+
default = false
60+
}
61+
62+
variable "install_ssh_key" {
63+
description = "SSH private key for installation"
64+
type = string
65+
default = ""
66+
sensitive = true
67+
}
68+
69+
# nixos-anywhere all-in-one module
70+
module "nixos_anywhere" {
71+
source = "../all-in-one"
72+
73+
nixos_system_attr = var.nixos_system_attr
74+
nixos_partitioner_attr = var.nixos_partitioner_attr
75+
target_host = var.target_host
76+
target_port = var.target_port
77+
target_user = var.target_user
78+
debug_logging = var.debug_logging
79+
phases = var.phases
80+
build_on_remote = var.build_on_remote
81+
install_ssh_key = var.install_ssh_key
82+
}
83+
84+
output "nixos_anywhere_result" {
85+
description = "nixos-anywhere module result"
86+
value = module.nixos_anywhere.result
87+
}

0 commit comments

Comments
 (0)