infra: introduce terraform/opentofu for proxmox management
- move ansible project within infra - introduce terraform/opentofu for proxmox VM management
This commit is contained in:
5
infra/terraform/.gitignore
vendored
Normal file
5
infra/terraform/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.env
|
||||
.terraform/
|
||||
.terraform.lock.hcl
|
||||
terraform.tfstate
|
||||
terraform.tfstate.backup
|
||||
25
infra/terraform/README.md
Normal file
25
infra/terraform/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
# Terraform Configuration
|
||||
|
||||
> This project uses OpenTofu instead of Terraform. OpenTofu is a fork of
|
||||
> Terraform that is compatible with Terraform configurations and provides
|
||||
> similar functionality.
|
||||
|
||||
This directory contains Terraform configurations for managing
|
||||
infrastructure resources. It includes configurations for Proxmox.
|
||||
|
||||
The plan is to eventually migrate all infrastructure management to Terraform,
|
||||
including Kubernetes clusters and other resources. Currently, the Proxmox
|
||||
configuration is fully managed by Terraform, while Kubernetes resources are
|
||||
managed using Helm charts and kubectl commands. Previously, the Proxmox
|
||||
configuration was managed using Ansible, but it has been migrated to Terraform
|
||||
for better consistency and state management.
|
||||
|
||||
The terraform state files are stored in a remote backend, which allows for
|
||||
collaboration and state management across different environments. The backend
|
||||
configuration is defined in the `backend.tf` file. The backend is set up to use
|
||||
minio as the storage backend.
|
||||
|
||||
## Proxmox
|
||||
|
||||
The Proxmox configuration is located in the `proxmox` directory.
|
||||
It uses the Proxmox provider to manage virtual machines and other resources.
|
||||
14
infra/terraform/proxmox/backend.tf
Normal file
14
infra/terraform/proxmox/backend.tf
Normal file
@ -0,0 +1,14 @@
|
||||
terraform {
|
||||
backend "s3" {
|
||||
bucket = "terraform-state" # Name of the MinIO bucket
|
||||
key = "proxmox/terraform.tfstate" # Path to the state file in the bucket
|
||||
endpoint = var.minio_endpoint # MinIO API endpoint
|
||||
access_key = var.minio_access_key # MinIO access key
|
||||
secret_key = var.minio_secret_key # MinIO secret key
|
||||
region = "us-east-1" # Arbitrary region (MinIO ignores this)
|
||||
skip_credentials_validation = true # Skip AWS-specific credential checks
|
||||
skip_metadata_api_check = true # Skip AWS metadata API checks
|
||||
skip_region_validation = true # Skip AWS region validation
|
||||
use_path_style = true # Use path-style URLs[](http://<host>/<bucket>)
|
||||
}
|
||||
}
|
||||
95
infra/terraform/proxmox/main.tf
Normal file
95
infra/terraform/proxmox/main.tf
Normal file
@ -0,0 +1,95 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
proxmox = {
|
||||
source = "bpg/proxmox"
|
||||
version = "0.78.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "proxmox" {
|
||||
endpoint = var.pm_api_url
|
||||
api_token = var.pm_api_token
|
||||
insecure = var.pm_insecure
|
||||
|
||||
ssh {
|
||||
agent = false
|
||||
username = var.pm_user
|
||||
private_key = file(var.pm_ssh_private_key_path)
|
||||
}
|
||||
}
|
||||
|
||||
data "local_file" "ssh_public_key" {
|
||||
filename = var.pm_ssh_public_key_path
|
||||
}
|
||||
|
||||
resource "proxmox_virtual_environment_vm" "ubuntu_vm" {
|
||||
for_each = { for vm in var.vms : vm.name => vm }
|
||||
|
||||
name = each.value.name
|
||||
node_name = each.value.node_name
|
||||
vm_id = each.value.vm_id
|
||||
|
||||
stop_on_destroy = true
|
||||
keyboard_layout = "fi"
|
||||
|
||||
initialization {
|
||||
ip_config {
|
||||
ipv4 {
|
||||
address = each.value.ip_address
|
||||
gateway = each.value.gateway
|
||||
}
|
||||
}
|
||||
|
||||
dns {
|
||||
servers = each.value.dns_servers
|
||||
}
|
||||
|
||||
datastore_id = "local"
|
||||
|
||||
user_account {
|
||||
username = var.vm_user_name
|
||||
password = var.vm_user_password
|
||||
keys = [trimspace(data.local_file.ssh_public_key.content)]
|
||||
}
|
||||
}
|
||||
|
||||
cpu {
|
||||
cores = each.value.cores
|
||||
sockets = 1
|
||||
}
|
||||
|
||||
memory {
|
||||
dedicated = each.value.memory
|
||||
}
|
||||
|
||||
disk {
|
||||
datastore_id = "local"
|
||||
file_id = proxmox_virtual_environment_download_file.ubuntu_cloud_image[each.value.node_name].id
|
||||
interface = "virtio0"
|
||||
iothread = true
|
||||
discard = "on"
|
||||
size = each.value.disk_size
|
||||
}
|
||||
|
||||
network_device {
|
||||
bridge = "vmbr0"
|
||||
}
|
||||
depends_on = [proxmox_virtual_environment_download_file.ubuntu_cloud_image]
|
||||
}
|
||||
|
||||
resource "proxmox_virtual_environment_download_file" "ubuntu_cloud_image" {
|
||||
for_each = toset(var.nodes)
|
||||
content_type = "iso"
|
||||
datastore_id = "local"
|
||||
node_name = each.key
|
||||
|
||||
url = "https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
|
||||
}
|
||||
|
||||
data "proxmox_virtual_environment_hosts" "hosts" {
|
||||
for_each = toset(var.nodes)
|
||||
node_name = each.key
|
||||
|
||||
depends_on = [proxmox_virtual_environment_vm.ubuntu_vm]
|
||||
}
|
||||
52
infra/terraform/proxmox/terraform.tfvars
Normal file
52
infra/terraform/proxmox/terraform.tfvars
Normal file
@ -0,0 +1,52 @@
|
||||
# Proxmox configuration =
|
||||
pm_ssh_public_key_path = "/home/taqi/.ssh/homeserver.pub"
|
||||
pm_ssh_private_key_path = "/home/taqi/.ssh/homeserver"
|
||||
|
||||
vms = [
|
||||
{
|
||||
name = "vm6"
|
||||
node_name = "homeserver1"
|
||||
vm_id = 105
|
||||
ip_address = "192.168.1.151/24"
|
||||
gateway = "192.168.1.1"
|
||||
dns_servers = ["192.168.1.145", "1.1.1.1"]
|
||||
cores = 2
|
||||
memory = 2048
|
||||
disk_size = 20
|
||||
},
|
||||
{
|
||||
name = "vm7"
|
||||
node_name = "homeserver1"
|
||||
vm_id = 106
|
||||
ip_address = "192.168.1.152/24"
|
||||
gateway = "192.168.1.1"
|
||||
dns_servers = ["192.168.1.145", "1.1.1.1"]
|
||||
cores = 2
|
||||
memory = 2048
|
||||
disk_size = 20
|
||||
},
|
||||
{
|
||||
name = "vm8"
|
||||
node_name = "homeserver2"
|
||||
vm_id = 205
|
||||
ip_address = "192.168.1.161/24"
|
||||
gateway = "192.168.1.1"
|
||||
dns_servers = ["192.168.1.145", "1.1.1.1"]
|
||||
cores = 2
|
||||
memory = 2048
|
||||
disk_size = 20
|
||||
},
|
||||
{
|
||||
name = "vm9"
|
||||
node_name = "homeserver2"
|
||||
vm_id = 206
|
||||
ip_address = "192.168.1.162/24"
|
||||
gateway = "192.168.1.1"
|
||||
dns_servers = ["192.168.1.145", "1.1.1.1"]
|
||||
cores = 2
|
||||
memory = 2048
|
||||
disk_size = 20
|
||||
}
|
||||
]
|
||||
|
||||
nodes = ["homeserver1", "homeserver2"]
|
||||
81
infra/terraform/proxmox/variables.tf
Normal file
81
infra/terraform/proxmox/variables.tf
Normal file
@ -0,0 +1,81 @@
|
||||
# variables for minio backend configuration
|
||||
variable "minio_access_key" {
|
||||
description = "MinIO access key"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "minio_secret_key" {
|
||||
description = "MinIO secret key"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "minio_endpoint" {
|
||||
description = "MinIO API endpoint"
|
||||
type = string
|
||||
}
|
||||
|
||||
# Variables for Proxmox configuration
|
||||
variable "pm_api_url" {
|
||||
description = "Proxmox API URL"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "pm_api_token" {
|
||||
description = "Proxmox password"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "pm_insecure" {
|
||||
description = "Allow insecure connections to Proxmox API"
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "pm_user" {
|
||||
description = "Proxmox user"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "pm_ssh_public_key_path" {
|
||||
description = "Path to SSH public key file"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "pm_ssh_private_key_path" {
|
||||
description = "Path to SSH private key file"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "vms" {
|
||||
description = "List of VMs to create"
|
||||
type = list(object({
|
||||
name = string
|
||||
node_name = string
|
||||
vm_id = number
|
||||
ip_address = string
|
||||
dns_servers = list(string)
|
||||
gateway = string
|
||||
cores = number
|
||||
memory = number
|
||||
disk_size = number
|
||||
}))
|
||||
}
|
||||
|
||||
variable "nodes" {
|
||||
type = list(string)
|
||||
default = ["homeserver1", "homeserver2"]
|
||||
}
|
||||
|
||||
variable "vm_user_name" {
|
||||
description = "Username for the VM"
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "vm_user_password" {
|
||||
description = "Password for the VM user"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
Reference in New Issue
Block a user