diff --git a/README.md b/README.md index 1c7d152..8ea36c4 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,13 @@ This repository contains reusable Terraform modules for managing Proxmox infrastructure. +*Modules in this repo are still in pre-1.0.0 version, so anything can change at any time.* + ## Provider in use -- [bpg/proxmox](https://registry.terraform.io/providers/bpg/proxmox/latest) For VMs, and image files. -- [telmate/proxmox](https://registry.terraform.io/namespaces/Telmate) For LXC containers. +- [bpg/proxmox](https://registry.terraform.io/providers/bpg/proxmox/latest). -## Available Modules +## Usage - [VM](proxmox/vm/) resource, [Example script](./usage/proxmox.vm.md). - [LXC](proxmox/lxc/) resource, [Example script](./usage/proxmox.lxc.md) diff --git a/proxmox/lxc/README.md b/proxmox/lxc/README.md index f1db3c8..f023e90 100644 --- a/proxmox/lxc/README.md +++ b/proxmox/lxc/README.md @@ -4,13 +4,17 @@ | Name | Version | |------|---------| | [terraform](#requirement\_terraform) | >= 1.5.7 | -| [proxmox](#requirement\_proxmox) | 3.0.1-rc6 | +| [local](#requirement\_local) | >= 2.5.1 | +| [proxmox](#requirement\_proxmox) | 0.70.0 | +| [random](#requirement\_random) | 3.6.3 | ## Providers | Name | Version | |------|---------| -| [proxmox](#provider\_proxmox) | 3.0.1-rc6 | +| [local](#provider\_local) | >= 2.5.1 | +| [proxmox](#provider\_proxmox) | 0.70.0 | +| [random](#provider\_random) | 3.6.3 | ## Modules @@ -20,24 +24,28 @@ No modules. | Name | Type | |------|------| -| [proxmox_lxc.lxc_container](https://registry.terraform.io/providers/telmate/proxmox/3.0.1-rc6/docs/resources/lxc) | resource | +| [proxmox_virtual_environment_container.lxc_container](https://registry.terraform.io/providers/bpg/proxmox/0.70.0/docs/resources/virtual_environment_container) | resource | +| [random_password.lxc_container_password](https://registry.terraform.io/providers/hashicorp/random/3.6.3/docs/resources/password) | resource | +| [local_file.ssh_public_key](https://registry.terraform.io/providers/hashicorp/local/latest/docs/data-sources/file) | data source | ## Inputs | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [container\_network\_interface](#input\_container\_network\_interface) | LXC container network interface name. Default value: `eth0`. | `string` | `"eth0"` | no | -| [disk\_name](#input\_disk\_name) | Proxmox storage pool (disk name) where the VM's disk should be stored. | `string` | n/a | yes | -| [disk\_size](#input\_disk\_size) | Disk size in Terrabyte (T), Gigabytes (G), Megabyte (M), or Kilobyte (K). For example, `8G` | `string` | n/a | yes | -| [host\_bridge\_network](#input\_host\_bridge\_network) | Default node's network device bridge. Default value: `vmbr0`. | `string` | `"vmbr0"` | no | -| [hostname](#input\_hostname) | LXC hostname. | `string` | n/a | yes | -| [ip\_address](#input\_ip\_address) | For setting static DHCP IP, add an IPv4 with CIDR notation. For example 10.20.30.40/24. Default value `dhcp`. | `string` | `"dhcp"` | no | -| [lxc\_template\_file](#input\_lxc\_template\_file) | Name of the LXC container template file. For example: ubuntu-20.04-standard\_20.04-1\_amd64.tar.gz | `string` | n/a | yes | -| [lxc\_template\_path](#input\_lxc\_template\_path) | Storage name where the LXC template is located. For example, `local` or `local-lvm`. | `string` | n/a | yes | -| [password](#input\_password) | Container login password. | `string` | n/a | yes | -| [proxmox\_node\_name](#input\_proxmox\_node\_name) | Proxmox node name where the container will be deployed. In a single-node environment, it's typically: `pve` | `string` | n/a | yes | -| [swap](#input\_swap) | A number that sets the amount of swap memory available to the container. Default is `0`. | `number` | `0` | no | -| [tags](#input\_tags) | Tags of the container in a single string and semicolon-delimited (e.g. `terraform;test`).. | `string` | `null` | no | +| [cpu\_cores](#input\_cpu\_cores) | The number of CPU cores | `number` | `1` | no | +| [description](#input\_description) | Container description | `string` | `"Manage by Terraform"` | no | +| [disk\_id](#input\_disk\_id) | Storage disk identifier (name) | `string` | n/a | yes | +| [disk\_size](#input\_disk\_size) | The size of the root filesystem in gigabytes (defaults to 4). When set to 0 a directory or zfs/btrfs subvolume will be created. Requires datastore\_id to be set. | `string` | `"4"` | no | +| [firewall](#input\_firewall) | Whether this interface's firewall rules should be used | `bool` | `true` | no | +| [hostname](#input\_hostname) | Hostname to assign to the container | `string` | n/a | yes | +| [ip\_config](#input\_ip\_config) | The IP configuration (default to dhcp) | `string` | `"dhcp"` | no | +| [memory](#input\_memory) | The dedicated memory in megabytes | `number` | `1024` | no | +| [network\_interface](#input\_network\_interface) | A network interface | `string` | `"eth0"` | no | +| [node\_name](#input\_node\_name) | The name of the node to assign the container to | `string` | n/a | yes | +| [os\_type](#input\_os\_type) | OS type: Alpine, Ubunt ...etc | `string` | `"unmanaged"` | no | +| [ssh\_public\_key\_path](#input\_ssh\_public\_key\_path) | Path to the local public key to be added to the default user's `.ssh/authorized_keys` file. | `string` | n/a | yes | +| [template\_file\_id](#input\_template\_file\_id) | The identifier for an OS template file. The ID format is :/, for example local:iso/jammy-server-cloudimg-amd64.tar.gz. | `string` | n/a | yes | +| [unprivileged](#input\_unprivileged) | Whether the container runs as unprivileged on the host | `bool` | `true` | no | ## Outputs diff --git a/proxmox/lxc/main.tf b/proxmox/lxc/main.tf index 5479034..a6f96d3 100644 --- a/proxmox/lxc/main.tf +++ b/proxmox/lxc/main.tf @@ -2,48 +2,81 @@ terraform { required_version = ">= 1.5.7" required_providers { proxmox = { - source = "telmate/proxmox" - version = "3.0.1-rc6" + source = "bpg/proxmox" + version = "0.70.0" + } + local = { + source = "hashicorp/local" + version = ">= 2.5.1" + } + random = { + source = "hashicorp/random" + version = "3.6.3" } } } -resource "proxmox_lxc" "lxc_container" { - target_node = var.proxmox_node_name - hostname = var.hostname - ostemplate = "${var.lxc_template_path}:vztmpl/${var.lxc_template_file}" - password = var.password - unprivileged = true - start = true - tags = var.tags - swap = var.swap - onboot = true - - # Terraform will crash without rootfs defined - rootfs { - # To allow LXC containers use 'local' pool storage, run this command on the host: - # pvesm set local --content backup,images,iso,rootdir,snippets,vztmpl - storage = var.disk_name - size = var.disk_size +data "local_file" "ssh_public_key" { + filename = var.ssh_public_key_path +} + +resource "proxmox_virtual_environment_container" "lxc_container" { + description = var.description + + node_name = var.node_name + # vm_id = 1234 + + initialization { + hostname = var.hostname + + ip_config { + ipv4 { + address = var.ip_config + } + } + + user_account { + keys = [ + trimspace(data.local_file.ssh_public_key.content) + ] + # Password is set randomly. Use ssh for login and change the password + password = random_password.lxc_container_password.result + + } + } + + network_interface { + name = var.network_interface + firewall = var.firewall + } + + operating_system { + # template_file_id = proxmox_virtual_environment_download_file.latest_ubuntu_22_jammy_lxc_img.id + template_file_id = var.template_file_id + # Or you can use a volume ID, as obtained from a "pvesm list " + # template_file_id = "local:vztmpl/jammy-server-cloudimg-amd64.tar.gz" + type = var.os_type } - network { - name = var.container_network_interface - bridge = var.host_bridge_network - ip = var.ip_address - # gw = The IPv4 address belonging to the network interface's default gateway. + cpu { + cores = var.cpu_cores } - # Additional LXC features. See provider docs: - # https://registry.terraform.io/providers/Telmate/proxmox/latest/docs/resources/lxc#lxc-with-advanced-features-enabled - # - # features { - # Allow running Docker on LXC. - # IMPORTANT! These features will expose the host's syscall, procfs and sysfs to the client. - # Know the implications of these actions before proceeding. - # See in https://pve.proxmox.com/wiki/Linux_Container - # keyctl = true - # nesting = true - # } + memory { + swap = 0 + dedicated = var.memory + } + + disk { + datastore_id = var.disk_id + size = var.disk_size + } + + unprivileged = var.unprivileged +} +resource "random_password" "lxc_container_password" { + length = 16 + override_special = "_%@" + special = true } diff --git a/proxmox/lxc/vars.tf b/proxmox/lxc/vars.tf index 45782e9..c3e143a 100644 --- a/proxmox/lxc/vars.tf +++ b/proxmox/lxc/vars.tf @@ -1,65 +1,78 @@ - -variable "proxmox_node_name" { +variable "description" { + default = "Manage by Terraform" type = string - description = "Proxmox node name where the container will be deployed. In a single-node environment, it's typically: `pve`" + description = "Container description" } -variable "hostname" { +variable "node_name" { type = string - description = "LXC hostname." + description = "The name of the node to assign the container to" } -variable "lxc_template_file" { +variable "hostname" { type = string - description = "Name of the LXC container template file. For example: ubuntu-20.04-standard_20.04-1_amd64.tar.gz" + description = "Hostname to assign to the container" } -variable "lxc_template_path" { +variable "ip_config" { + default = "dhcp" type = string - description = "Storage name where the LXC template is located. For example, `local` or `local-lvm`." + description = "The IP configuration (default to dhcp)" } -variable "password" { +variable "network_interface" { + default = "eth0" type = string - description = "Container login password." + description = "A network interface" } -variable "tags" { - default = null +variable "template_file_id" { type = string - description = "Tags of the container in a single string and semicolon-delimited (e.g. `terraform;test`).." + description = "The identifier for an OS template file. The ID format is :/, for example local:iso/jammy-server-cloudimg-amd64.tar.gz." } -variable "swap" { - default = 0 - type = number - description = "A number that sets the amount of swap memory available to the container. Default is `0`." +variable "os_type" { + default = "unmanaged" + type = string + description = "OS type: Alpine, Ubunt ...etc" } -variable "disk_name" { +variable "disk_id" { type = string - description = "Proxmox storage pool (disk name) where the VM's disk should be stored." + description = "Storage disk identifier (name)" } variable "disk_size" { + default = "4" type = string - description = "Disk size in Terrabyte (T), Gigabytes (G), Megabyte (M), or Kilobyte (K). For example, `8G`" + description = "The size of the root filesystem in gigabytes (defaults to 4). When set to 0 a directory or zfs/btrfs subvolume will be created. Requires datastore_id to be set." } -variable "container_network_interface" { - default = "eth0" +variable "ssh_public_key_path" { type = string - description = "LXC container network interface name. Default value: `eth0`." + description = "Path to the local public key to be added to the default user's `.ssh/authorized_keys` file." } -variable "host_bridge_network" { - default = "vmbr0" - type = string - description = "Default node's network device bridge. Default value: `vmbr0`." +variable "memory" { + default = 1024 + type = number + description = "The dedicated memory in megabytes" } -variable "ip_address" { - default = "dhcp" - type = string - description = "For setting static DHCP IP, add an IPv4 with CIDR notation. For example 10.20.30.40/24. Default value `dhcp`." +variable "unprivileged" { + default = true + type = bool + description = "Whether the container runs as unprivileged on the host" +} + +variable "firewall" { + default = true + type = bool + description = "Whether this interface's firewall rules should be used" +} + +variable "cpu_cores" { + default = 1 + type = number + description = "The number of CPU cores" } diff --git a/proxmox/vm/README.md b/proxmox/vm/README.md index 7148b3f..267593f 100644 --- a/proxmox/vm/README.md +++ b/proxmox/vm/README.md @@ -33,7 +33,7 @@ No modules. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| [cloud\_image\_info](#input\_cloud\_image\_info) | A list of strings as the following:
index 0 for storage pool (disk) name where the cloud image iso, img, qcow... etc is stored.
index 1 for cloud-image file name (it must end with `.img` extension)
For example: `cloud_image_info: ["local-lvm", "debian-12-generic.qcow2.img"]`. | `list(string)` | n/a | yes | +| [cloud\_image\_info](#input\_cloud\_image\_info) | A list of strings as the following:
index 0 for storage pool (disk) name where the cloud image iso, img, qcow... etc is stored.
index 1 for cloud-image file name (it must end with `.img` extension)
For example: `cloud_image_info: ["local-lvm", "debian-12-generic.qcow2.img"]`. | `list(string)` | n/a | yes | | [cores](#input\_cores) | The number of CPU cores. | `number` | `1` | no | | [cpu\_type](#input\_cpu\_type) | The emulated CPU type. Some VMs need certain types of CPUs. See available values in https://registry.terraform.io/providers/bpg/proxmox/latest/docs/resources/virtual_environment_vm#host | `string` | `"qemu64"` | no | | [description](#input\_description) | VM resource description. | `string` | `"Managed by Terraform"` | no | @@ -46,7 +46,7 @@ No modules. | [network\_interface](#input\_network\_interface) | Default node's network device bridge. Default value: `vmbr0`. | `string` | `"vmbr0"` | no | | [proxmox\_node\_name](#input\_proxmox\_node\_name) | Proxmox node name. In a single-node environment, it's typically: `pve` | `string` | n/a | yes | | [sockets](#input\_sockets) | The number of CPU sockets. | `number` | `1` | no | -| [ssh\_public\_key\_path](#input\_ssh\_public\_key\_path) | Path to the public SSH key to allow the default user SSH into the VM. | `string` | n/a | yes | +| [ssh\_public\_key\_path](#input\_ssh\_public\_key\_path) | Path to the local public key to be added to the default user's `.ssh/authorized_keys` file. | `string` | n/a | yes | | [tags](#input\_tags) | List of strings for tags. For example: ['terraform', 'ubuntu']. | `list(string)` |
[
"terraform"
]
| no | | [temp\_user\_password](#input\_temp\_user\_password) | Temorary login password. Upon the first login, a prompt to change the password will be presented. | `string` | `"changeme"` | no | | [timezone](#input\_timezone) | Timezone to be configured via `timedatectl` in cloud-init template. | `string` | n/a | yes | diff --git a/proxmox/vm/vars.tf b/proxmox/vm/vars.tf index c795e25..1a720a3 100644 --- a/proxmox/vm/vars.tf +++ b/proxmox/vm/vars.tf @@ -80,7 +80,7 @@ variable "network_interface" { variable "cloud_image_info" { type = list(string) description = <