Initial commit: Terraform vSphere resource groups module

- Add vSphere resource pool management
- Configure CPU and memory allocation controls
- Implement tagging system for organization
- Add comprehensive documentation
This commit is contained in:
Patrick de Ruiter 2025-11-01 06:18:59 +01:00
commit 560200bb3c
Signed by: pderuiter
GPG Key ID: 5EBA7F21CF583321
8 changed files with 374 additions and 0 deletions

58
.gitignore vendored Normal file
View File

@ -0,0 +1,58 @@
# Local .terraform directories
**/.terraform/*
# .tfstate files
*.tfstate
*.tfstate.*
# Crash log files
crash.log
crash.*.log
# Exclude all .tfvars files, which are likely to contain sensitive data
*.tfvars
*.tfvars.json
# Ignore override files as they are usually used to override resources locally
override.tf
override.tf.json
*_override.tf
*_override.tf.json
# Include override files you do wish to add to version control using negated pattern
# !example_override.tf
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
*tfplan*
# Ignore CLI configuration files
.terraformrc
terraform.rc
# Ignore lock files (optional, some prefer to commit these)
.terraform.lock.hcl
# Ansible directories
ansible/
**/ansible/
# SSH keys and sensitive files
*.pem
*.key
**/files/kubernetes_key*
**/files/*_key
# OS files
.DS_Store
Thumbs.db
# IDE files
.idea/
.vscode/
*.swp
*.swo
*~
# Backup files
*.backup
*.bak

70
README.md Normal file
View File

@ -0,0 +1,70 @@
# Terraform vSphere Resource Groups Module
This Terraform module manages vSphere resource pools (resource groups) with CPU/memory allocation controls and integrated tagging for organization and management.
## Purpose
Creates and manages vSphere resource pools with configurable resource allocation policies, reservations, limits, and shares. Includes automated tagging for environment and resource group classification.
## What It Does
1. Creates resource pools under vSphere cluster
2. Configures CPU reservations, limits, and shares
3. Configures memory reservations, limits, and shares
4. Creates tag categories for Environment and ResourceGroupType
5. Applies tags to resource pools for organization
## Usage
```hcl
module "vsphere_resource_groups" {
source = "./terraform-vsphere-resourcegroups"
datacenter = "DC1"
cluster_name = "Cluster01"
environment = "prod"
role_id = var.vault_role_id
secret_id = var.vault_secret_id
resource_groups = {
kubernetes = {
name = "Kubernetes"
cpu_reservation = 4000
cpu_shares = "high"
memory_reservation = 8192
memory_shares = "high"
}
docker = {
name = "Docker"
cpu_shares = "normal"
memory_shares = "normal"
}
infra = {
name = "Infrastructure"
cpu_shares = "low"
memory_shares = "low"
}
}
}
```
## Key Features
- **Resource Allocation**: CPU and memory reservations, limits, shares
- **Shares Mapping**: Automatic conversion of low/normal/high to vSphere values (500/1000/2000)
- **Tagging System**: Environment and resource group type tags
- **Flexible Configuration**: Optional parameters with sensible defaults
- **Expandable Resources**: Allow resources to grow beyond reservations
## Default Resource Groups
- **Kubernetes**: For Kubernetes infrastructure
- **Docker**: For Docker containers
- **Infra**: For infrastructure services
## Prerequisites
- VMware vSphere with compute cluster
- Vault with vSphere credentials
- Terraform >= 0.13

20
backend.tf Normal file
View File

@ -0,0 +1,20 @@
terraform {
backend "s3" {
endpoints = {
s3 = "https://minio.bsdserver.nl:443"
}
bucket = "home-terraform"
key = "home/vsphere/network/vsphere-resourcegroup-config.tfstate"
access_key = "R9lCycfEO8qJ2dxlQT1S"
secret_key = "6rtVLjDIjx7U9ecNRkdbS3idSBNWsfNhN6wB20sJ"
region = "main"
skip_credentials_validation = true
skip_metadata_api_check = true
skip_requesting_account_id = true
skip_region_validation = true
use_path_style = true
}
}

17
data.tf Normal file
View File

@ -0,0 +1,17 @@
data "vault_generic_secret" "vmware" {
path = "secret/vmware"
}
data "vsphere_datacenter" "dc" {
name = var.datacenter
}
data "vsphere_compute_cluster" "cluster" {
name = var.cluster_name
datacenter_id = data.vsphere_datacenter.dc.id
}
data "vsphere_host" "host" {
name = "esxi101.bsdserver.lan"
datacenter_id = data.vsphere_datacenter.dc.id
}

63
main.tf Normal file
View File

@ -0,0 +1,63 @@
locals {
shares_mapping = {
"low" = 500
"normal" = 1000
"high" = 2000
}
}
resource "vsphere_resource_pool" "resource_groups" {
for_each = var.resource_groups
name = each.value.name
parent_resource_pool_id = data.vsphere_compute_cluster.cluster.resource_pool_id
cpu_reservation = each.value.cpu_reservation
cpu_expandable = each.value.cpu_expandable
cpu_limit = each.value.cpu_limit
cpu_shares = lookup(local.shares_mapping, each.value.cpu_shares, 1000)
memory_reservation = each.value.memory_reservation
memory_expandable = each.value.memory_expandable
memory_limit = each.value.memory_limit
memory_shares = lookup(local.shares_mapping, each.value.memory_shares, 1000)
tags = [
vsphere_tag.environment.id,
vsphere_tag.resource_group[each.key].id
]
}
resource "vsphere_tag_category" "environment" {
name = "Environment"
description = "Environment category for resource groups"
cardinality = "SINGLE"
associable_types = [
"ResourcePool",
]
}
resource "vsphere_tag" "environment" {
name = var.environment
category_id = vsphere_tag_category.environment.id
description = "Environment tag for ${var.environment}"
}
resource "vsphere_tag_category" "resource_group_type" {
name = "ResourceGroupType"
description = "Resource group type category"
cardinality = "SINGLE"
associable_types = [
"ResourcePool",
]
}
resource "vsphere_tag" "resource_group" {
for_each = var.resource_groups
name = each.key
category_id = vsphere_tag_category.resource_group_type.id
description = "Resource group tag for ${each.value.name}"
}

25
outputs.tf Normal file
View File

@ -0,0 +1,25 @@
output "resource_pool_ids" {
description = "Map of resource group names to their resource pool IDs"
value = {
for k, v in vsphere_resource_pool.resource_groups : k => v.id
}
}
output "resource_pool_names" {
description = "Map of resource group keys to their display names"
value = {
for k, v in var.resource_groups : k => v.name
}
}
output "environment_tag_id" {
description = "ID of the environment tag"
value = vsphere_tag.environment.id
}
output "resource_group_tag_ids" {
description = "Map of resource group tag IDs"
value = {
for k, v in vsphere_tag.resource_group : k => v.id
}
}

31
provider.tf Normal file
View File

@ -0,0 +1,31 @@
terraform {
required_providers {
vsphere = {
source = "vmware/vsphere"
}
vault = {
source = "hashicorp/vault"
}
}
}
# Configure the Vault provider
provider "vault" {
address = "https://wbyc-srv-docker01.bsdserver.lan:8200"
auth_login {
path = "auth/approle/login"
parameters = {
role_id = var.role_id
secret_id = var.secret_id
}
}
}
# vSphere Provider
provider "vsphere" {
vsphere_server = data.vault_generic_secret.vmware.data["vcenter_server"]
user = data.vault_generic_secret.vmware.data["vcenter_username"]
password = data.vault_generic_secret.vmware.data["vcenter_password"]
allow_unverified_ssl = true
}

90
variables.tf Normal file
View File

@ -0,0 +1,90 @@
variable "datacenter" {
description = "vSphere data center"
type = string
}
variable "cluster_name" {
description = "vSphere Cluster Name"
type = string
}
# Environment
variable "environment" {
description = "Environment name can be: dev, tst, acc, uat, prod, shared or tools"
type = string
}
# Resource Groups
variable "resource_groups" {
type = map(object({
name = string
cpu_reservation = optional(number, 0)
cpu_expandable = optional(bool, true)
cpu_limit = optional(number, -1)
cpu_shares = optional(string, "normal")
memory_reservation = optional(number, 0)
memory_expandable = optional(bool, true)
memory_limit = optional(number, -1)
memory_shares = optional(string, "normal")
}))
description = "Map of resource groups to create"
default = {
kubernetes = {
name = "Kubernetes"
}
docker = {
name = "Docker"
}
infra = {
name = "Infra"
}
}
}
# Vault approle
variable "role_id" {
description = "Role ID for Vault AppRole authentication"
type = string
sensitive = true
}
variable "secret_id" {
description = "Secret ID for Vault AppRole authentication"
type = string
sensitive = true
}
# Domain
variable "domain" {
description = "Domain name"
type = string
default = ""
}
# ESXi Hosts
variable "esxi_hosts" {
description = "Map of ESXi hosts configuration"
type = map(object({
name = string
ip_address = string
tags = optional(map(string), {})
}))
default = {}
}
# Port Groups
variable "port_groups" {
description = "Map of port groups configuration"
type = map(object({
vlan_id = number
allow_promiscuous = optional(bool, false)
subnet_address = string
subnet_mask = number
gateway_ip = string
nameserver_id = number
hosts = list(string)
}))
default = {}
}