commit 560200bb3c2ffee388257986d8088861b7ffac6d Author: Patrick de Ruiter Date: Sat Nov 1 06:18:59 2025 +0100 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 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..46562e3 --- /dev/null +++ b/.gitignore @@ -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 diff --git a/README.md b/README.md new file mode 100644 index 0000000..9511fc8 --- /dev/null +++ b/README.md @@ -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 diff --git a/backend.tf b/backend.tf new file mode 100644 index 0000000..a02f2f4 --- /dev/null +++ b/backend.tf @@ -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 + } +} diff --git a/data.tf b/data.tf new file mode 100644 index 0000000..29d2011 --- /dev/null +++ b/data.tf @@ -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 +} diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..4c760f4 --- /dev/null +++ b/main.tf @@ -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}" +} diff --git a/outputs.tf b/outputs.tf new file mode 100644 index 0000000..6c10a5a --- /dev/null +++ b/outputs.tf @@ -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 + } +} \ No newline at end of file diff --git a/provider.tf b/provider.tf new file mode 100644 index 0000000..6442cb3 --- /dev/null +++ b/provider.tf @@ -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 +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..f8c79fb --- /dev/null +++ b/variables.tf @@ -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 = {} +}