Scaffold incremental Terraform foundations for docker and proxmox
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
.terraform/
|
||||||
|
*.tfstate
|
||||||
|
*.tfstate.*
|
||||||
|
*.tfvars
|
||||||
|
*.tfvars.json
|
||||||
|
crash.log
|
||||||
|
override.tf
|
||||||
|
override.tf.json
|
||||||
|
*_override.tf
|
||||||
|
*_override.tf.json
|
||||||
|
*.tfplan
|
||||||
|
plan.out
|
||||||
|
state/
|
||||||
|
artifacts/
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
# Terraform foundations
|
||||||
|
|
||||||
|
This directory introduces Terraform in a conservative, incremental way for this homelab repo.
|
||||||
|
|
||||||
|
## Purpose in this repository
|
||||||
|
|
||||||
|
Terraform is used here to **document and gradually adopt management** of existing infrastructure without disrupting running services.
|
||||||
|
|
||||||
|
Current intent:
|
||||||
|
- Start with imported live Docker resources so infrastructure is visible and reproducible in code.
|
||||||
|
- Add Proxmox inventory/configuration later once provider details and import IDs are confirmed.
|
||||||
|
- Keep this phase local-state and learning-oriented (no remote backend yet).
|
||||||
|
|
||||||
|
## Tool boundaries
|
||||||
|
|
||||||
|
- **Docker Compose**: day-to-day application/service runtime definitions already used by this repo.
|
||||||
|
- **Terraform**: infrastructure state capture and controlled resource management (starting with imports).
|
||||||
|
- **Ansible**: follow-on host/configuration management after Terraform inventory and targets are stable.
|
||||||
|
- **NixOS**: host OS/system-level declarative configuration, separate from per-service compose workflows.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
|
||||||
|
- `docker/`: Docker provider scaffold and incremental import workflow.
|
||||||
|
- `proxmox/`: placeholder scaffold for later Proxmox adoption.
|
||||||
|
- `modules/`: placeholder module directories for future shared patterns.
|
||||||
|
|
||||||
|
## Incremental adoption plan
|
||||||
|
|
||||||
|
1. Import Docker containers one-by-one into Terraform state.
|
||||||
|
2. Reconcile and stabilize Docker Terraform configuration until `terraform plan` is clean.
|
||||||
|
3. Add Proxmox inventory/configuration scaffolding and imports later.
|
||||||
|
4. Introduce Ansible workflow after Terraform-managed inventory is trustworthy.
|
||||||
|
|
||||||
|
## Safety notes
|
||||||
|
|
||||||
|
- State files are intentionally gitignored for safety and portability.
|
||||||
|
- Do **not** run `terraform apply` until imported resources are fully reconciled and plan output is reviewed as no-op for intended targets.
|
||||||
|
- No remote backend is configured yet by design.
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# Docker Terraform scaffold
|
||||||
|
|
||||||
|
This directory is for **incremental, import-first Terraform adoption** of existing Docker containers.
|
||||||
|
|
||||||
|
## What this directory is for
|
||||||
|
|
||||||
|
- Document existing live Docker resources in Terraform.
|
||||||
|
- Import containers one-by-one.
|
||||||
|
- Reconcile Terraform code with real runtime values until plan is clean.
|
||||||
|
|
||||||
|
## Initialize
|
||||||
|
|
||||||
|
From this directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
terraform init
|
||||||
|
```
|
||||||
|
|
||||||
|
## Safe incremental import workflow
|
||||||
|
|
||||||
|
1. Add one `docker_container` resource block in `main.tf` for an already-running container.
|
||||||
|
2. Import it into state:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
terraform import docker_container.<resource_name> <container_id_or_container_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Inspect imported state:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
terraform state show docker_container.<resource_name>
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Copy required/meaningful arguments from state output into `main.tf`.
|
||||||
|
5. Run `terraform plan` and refine until there are no unintended changes.
|
||||||
|
|
||||||
|
## Reconciliation guidance
|
||||||
|
|
||||||
|
- Keep one resource block per imported container.
|
||||||
|
- Prefer explicit values for arguments that affect recreation.
|
||||||
|
- Avoid broad changes; reconcile each container independently.
|
||||||
|
- Do **not** run `terraform apply` until plan output is intentionally clean.
|
||||||
|
|
||||||
|
## State and secrets handling
|
||||||
|
|
||||||
|
- State files are ignored via `../.gitignore` because they may contain environment-specific metadata.
|
||||||
|
- Do not commit real `.tfvars` files with machine-specific values.
|
||||||
|
- Use `terraform.tfvars.example` as a safe starter template.
|
||||||
@@ -1,16 +1,17 @@
|
|||||||
terraform {
|
# Docker Terraform workflow in this repo:
|
||||||
required_providers {
|
# 1) Add a minimal resource block for ONE existing container.
|
||||||
docker = {
|
# 2) Import that live container into state:
|
||||||
source = "kreuzwerker/docker"
|
# terraform import docker_container.<name> <container_id_or_name>
|
||||||
version = "~> 3.0"
|
# 3) Inspect imported arguments:
|
||||||
}
|
# terraform state show docker_container.<name>
|
||||||
}
|
# 4) Copy required arguments into this file and refine.
|
||||||
}
|
# 5) Repeat until terraform plan shows no unintended changes.
|
||||||
|
|
||||||
provider "docker" {
|
# Example skeleton for future imported containers (intentionally commented):
|
||||||
host = "unix:///var/run/docker.sock"
|
# resource "docker_container" "example_service" {
|
||||||
}
|
# name = "existing-container-name"
|
||||||
resource "docker_container" "searxng" {
|
# image = "repo/image:tag"
|
||||||
name = "searxng-webapp"
|
#
|
||||||
image = "searxng/searxng"
|
# # Add additional arguments based on `terraform state show` output.
|
||||||
}
|
# # Keep values aligned with the live container so plan is a no-op.
|
||||||
|
# }
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
output "docker_host_in_use" {
|
||||||
|
description = "Docker daemon endpoint currently targeted by this workspace."
|
||||||
|
value = var.docker_host
|
||||||
|
}
|
||||||
|
|
||||||
|
output "managed_container_names" {
|
||||||
|
description = "Names of containers intentionally tracked in Terraform configuration."
|
||||||
|
value = var.managed_container_names
|
||||||
|
}
|
||||||
|
|
||||||
|
output "import_reconciliation_steps" {
|
||||||
|
description = "Short reminder of the safe import-first workflow."
|
||||||
|
value = [
|
||||||
|
"Create one docker_container block for an existing container.",
|
||||||
|
"Run terraform import for that block.",
|
||||||
|
"Run terraform state show and copy required arguments.",
|
||||||
|
"Refine config until terraform plan has no unintended changes.",
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
provider "docker" {
|
||||||
|
# Local Docker socket default for incremental import/documentation workflow.
|
||||||
|
host = var.docker_host
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Example only. Copy to terraform.tfvars for local use if needed.
|
||||||
|
# Do not commit host-specific overrides.
|
||||||
|
|
||||||
|
# docker_host = "unix:///var/run/docker.sock"
|
||||||
|
|
||||||
|
# Optional: list container names intentionally tracked in Terraform outputs.
|
||||||
|
managed_container_names = [
|
||||||
|
"example-container-name"
|
||||||
|
]
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
variable "docker_host" {
|
||||||
|
description = "Docker daemon host for local import workflow."
|
||||||
|
type = string
|
||||||
|
default = "unix:///var/run/docker.sock"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "managed_container_names" {
|
||||||
|
description = "Human-maintained list of containers intentionally tracked in Terraform docs/outputs."
|
||||||
|
type = list(string)
|
||||||
|
default = []
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
terraform {
|
||||||
|
required_version = ">= 1.6.0"
|
||||||
|
|
||||||
|
required_providers {
|
||||||
|
docker = {
|
||||||
|
source = "kreuzwerker/docker"
|
||||||
|
version = "3.0.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# docker_container_placeholder module
|
||||||
|
|
||||||
|
Placeholder module directory for future shared Docker container patterns.
|
||||||
|
|
||||||
|
This is intentionally empty during initial import-first adoption.
|
||||||
|
Keep per-container resources explicit in `../../docker/main.tf` until stable patterns emerge.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# proxmox_vm_placeholder module
|
||||||
|
|
||||||
|
Placeholder module directory for future shared Proxmox VM patterns.
|
||||||
|
|
||||||
|
This is intentionally empty until provider schemas, import ID formats,
|
||||||
|
and non-destructive reconciliation strategy are validated.
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# Proxmox Terraform scaffold
|
||||||
|
|
||||||
|
This directory is a **placeholder scaffold** for future Proxmox Terraform adoption.
|
||||||
|
|
||||||
|
## What this directory is for
|
||||||
|
|
||||||
|
- Prepare provider/version/variable structure now.
|
||||||
|
- Delay real Proxmox resource management until import strategy is validated.
|
||||||
|
|
||||||
|
## Initialize
|
||||||
|
|
||||||
|
From this directory:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
terraform init
|
||||||
|
```
|
||||||
|
|
||||||
|
## Current status
|
||||||
|
|
||||||
|
- No live Proxmox resources are defined yet.
|
||||||
|
- Provider auth variables are placeholders only.
|
||||||
|
- Import IDs and resource schemas must be verified against provider docs before adding resources.
|
||||||
|
|
||||||
|
## Future safe workflow
|
||||||
|
|
||||||
|
1. Add one resource block for an existing VM/object.
|
||||||
|
2. Import it with the provider-specific ID format.
|
||||||
|
3. Inspect with `terraform state show`.
|
||||||
|
4. Reconcile `.tf` arguments until `terraform plan` is clean.
|
||||||
|
5. Repeat incrementally.
|
||||||
|
|
||||||
|
## Safety notes
|
||||||
|
|
||||||
|
- Do not commit real credentials in `.tf` files or tracked `.tfvars`.
|
||||||
|
- State files are ignored by the Terraform-level `.gitignore`.
|
||||||
|
- Do not run `terraform apply` until plan is intentionally no-op for existing resources.
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Proxmox scaffold only.
|
||||||
|
#
|
||||||
|
# IMPORTANT:
|
||||||
|
# - Resource blocks are intentionally omitted for now.
|
||||||
|
# - Before adding resources, confirm:
|
||||||
|
# 1) provider resource schemas,
|
||||||
|
# 2) exact import ID formats,
|
||||||
|
# 3) non-destructive reconciliation strategy for existing VMs.
|
||||||
|
#
|
||||||
|
# Suggested future workflow mirrors docker/:
|
||||||
|
# - Define one resource for an existing object.
|
||||||
|
# - Import it.
|
||||||
|
# - Use `terraform state show` to reconcile config.
|
||||||
|
# - Proceed incrementally.
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
output "proxmox_scaffold_ready" {
|
||||||
|
description = "Indicates this directory is a placeholder scaffold for future Proxmox adoption."
|
||||||
|
value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
output "proxmox_endpoint_configured" {
|
||||||
|
description = "Whether a non-empty endpoint has been provided."
|
||||||
|
value = var.proxmox_endpoint != ""
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
provider "proxmox" {
|
||||||
|
# Placeholder-only scaffold.
|
||||||
|
# Confirm exact provider auth mode and endpoint details before real use.
|
||||||
|
endpoint = var.proxmox_endpoint
|
||||||
|
insecure = var.proxmox_insecure
|
||||||
|
|
||||||
|
username = var.proxmox_username
|
||||||
|
password = var.proxmox_password
|
||||||
|
|
||||||
|
api_token = var.proxmox_api_token
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# Example placeholders only. Do not commit real credentials.
|
||||||
|
|
||||||
|
proxmox_endpoint = "https://pve.example.local:8006/api2/json"
|
||||||
|
proxmox_insecure = false
|
||||||
|
|
||||||
|
# Use either username/password or API token based on your chosen auth flow.
|
||||||
|
proxmox_username = "root@pam"
|
||||||
|
proxmox_password = "REPLACE_ME"
|
||||||
|
proxmox_api_token = "REPLACE_ME"
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
variable "proxmox_endpoint" {
|
||||||
|
description = "Proxmox API endpoint URL, for example https://pve.example.local:8006/api2/json"
|
||||||
|
type = string
|
||||||
|
default = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "proxmox_insecure" {
|
||||||
|
description = "Set true only for local testing with self-signed TLS; prefer false in stable environments."
|
||||||
|
type = bool
|
||||||
|
default = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "proxmox_username" {
|
||||||
|
description = "Username for password-based auth (placeholder; optional if token auth is used)."
|
||||||
|
type = string
|
||||||
|
default = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "proxmox_password" {
|
||||||
|
description = "Password for password-based auth (placeholder; optional if token auth is used)."
|
||||||
|
type = string
|
||||||
|
default = ""
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "proxmox_api_token" {
|
||||||
|
description = "API token for token-based auth (placeholder; optional if username/password is used)."
|
||||||
|
type = string
|
||||||
|
default = ""
|
||||||
|
sensitive = true
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
terraform {
|
||||||
|
required_version = ">= 1.6.0"
|
||||||
|
|
||||||
|
required_providers {
|
||||||
|
proxmox = {
|
||||||
|
source = "bpg/proxmox"
|
||||||
|
version = "0.68.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user