Skip to content

Hashicorp Terraform

Terraform is an infrastructure as code tool that lets you build, change, and version infrastructure safely and efficiently. This includes low-level components like compute instances, storage, and networking, as well as high-level components like DNS entries and SaaS features.

jamlab-terraform: Terraform configurations for provisioning homelab VMs.

Usage

With existing VM template(s) built with Proxmox Builder (ISO) it is possible to provision VMs with Terraform extra fast using Terraform Proxmox provider.

Initializing and verifying configuration

Initialize the configuration directory to download and install the providers defined in the configuration:

Bash
terraform init

Format your configurations. Terraform will print out the names of the files it modified, if any:

Bash
terraform fmt

Make sure your configuration is syntactically valid and internally consistent

Bash
terraform validate

Provisioning

Execute a dry run to verify configuration and see what would be done before executing apply:

Bash
terraform plan

Apply the plan and provision infrastructure as declared in configurations:

Bash
terraform apply

Note: use the -auto-approve flag to skip interactive approval of plan before applying.

Unprovision infrastructure as declared in configurations:

Bash
terraform destroy

Using -compact-warnings flag will compact output, but still outputs errors in full.

Targeting specific resources

Any resources defined in main.tf can be targeted by using -target="<RESOURCE>.<RESOURCE NAME>".

For example, target base-infra module:

Bash
terraform apply -target=module.base-infra

Structure

Text Only
main.tf                      # Main file used by Terraform commands
variables.tf                 # Global variables

modules/                     # Reusable modules
    pve-vm/                  # Proxmox VE VM provisioning template module

envs/                        # Environments dir
    prod/                    # Production infra definitions
        base-infra/          # Base infrastructure needed for services
            vars.tf          # Input variables
            outputs.tf       # Output variables
            main.tf          # Resources to be provisioned using modules
        service-infra/       # Services infrastructure
    dev/                     # Development infra definitions
       dev-vm/               # Development VM

Creating multiple of similar resource

Create variable to be looped over with the values that will be used for each loop:

Text Only
variable "vms" {
  description = "Base Infrastructure Virtual Machines"
  type = map
  default = {
  vm0 = {
        name = "vb0"
        ip   = "192.168.0.120"
    }
  vm1 = {
        name = "vb1"
        ip   = "192.168.0.121"
  }
 }
}

And then use for_each to use the variable to be looped over using the values with keyword each.value.<VALUE INSIDE LOOPED VARIABLE>:

Text Only
module "vm" {
  for_each = var.vms
  source = "../../../modules/pve-vm" 

  target_node = local.default_target_node
  clone = local.default_clone
  vm_name = each.value.name
  desc = local.desc
  ipconfig0 = "ip=${each.value.ip}${local.cidr},gw=${local.gateway}"
  ip_address = "${each.value.ip}"
...