commit 68cd598f25c4654294c37b883baa4bd62aa572bf Author: Robert Kaussow Date: Wed Jan 17 21:35:42 2024 +0100 first commit diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..bf61628 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +/terraform/.terraform + +*.retry +*.tfvars +*.tfstate +.terraform.lock.hcl + +.vaultpasswd +.envrc + +/galaxy diff --git a/.gitsv/config.yml b/.gitsv/config.yml new file mode 100644 index 0000000..7b9cae5 --- /dev/null +++ b/.gitsv/config.yml @@ -0,0 +1,47 @@ +--- +version: "1.1" + +versioning: + update-major: [] + update-minor: [feat] + update-patch: [fix, perf, refactor, chore, test, ci, docs] + +tag: + pattern: "v%d.%d.%d" + +release-notes: + sections: + - name: Features + commit-types: [feat] + section-type: commits + - name: Bug Fixes + commit-types: [fix] + section-type: commits + - name: Performance Improvements + commit-types: [perf] + section-type: commits + - name: Code Refactoring + commit-types: [refactor] + section-type: commits + - name: Others + commit-types: [chore] + section-type: commits + - name: Testing + commit-types: [test] + section-type: commits + - name: CI Pipeline + commit-types: [ci] + section-type: commits + - name: Documentation + commit-types: [docs] + section-type: commits + - name: Breaking Changes + section-type: breaking-changes + +commit-message: + footer: + issue: + key: issue + add-value-prefix: "#" + issue: + regex: "#?[0-9]+" diff --git a/.renovaterc.json b/.renovaterc.json new file mode 100644 index 0000000..bf73d46 --- /dev/null +++ b/.renovaterc.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": ["github>thegeeklab/renovate-presets"] +} diff --git a/.tflint.hcl b/.tflint.hcl new file mode 100644 index 0000000..299bcc6 --- /dev/null +++ b/.tflint.hcl @@ -0,0 +1,16 @@ +plugin "terraform" { + enabled = true + preset = "recommended" +} + +rule "terraform_required_version" { + enabled = false +} + +rule "terraform_required_providers" { + enabled = false +} + +rule "terraform_unused_declarations" { + enabled = false +} diff --git a/.woodpecker/build-package.yml b/.woodpecker/build-package.yml new file mode 100644 index 0000000..7a4c484 --- /dev/null +++ b/.woodpecker/build-package.yml @@ -0,0 +1,28 @@ +--- +when: + - event: [pull_request, tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +steps: + - name: changelog + image: quay.io/thegeeklab/git-sv + commands: + - git sv current-version + - git sv release-notes -t ${CI_COMMIT_TAG:-next} -o CHANGELOG.md + - cat CHANGELOG.md + + - name: publish-gitea + image: quay.io/thegeeklab/wp-gitea-release + settings: + api_key: + from_secret: gitea_token + base_url: https://gitea.rknet.org + note: CHANGELOG.md + title: ${CI_COMMIT_TAG} + when: + - event: [tag] + +depends_on: + - test diff --git a/.woodpecker/notify.yml b/.woodpecker/notify.yml new file mode 100644 index 0000000..9957125 --- /dev/null +++ b/.woodpecker/notify.yml @@ -0,0 +1,26 @@ +--- +when: + - event: [tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +runs_on: [success, failure] + +steps: + - name: matrix + image: quay.io/thegeeklab/wp-matrix + settings: + homeserver: + from_secret: matrix_homeserver + password: + from_secret: matrix_password + roomid: + from_secret: matrix_roomid + username: + from_secret: matrix_username + when: + - status: [success, failure] + +depends_on: + - docs diff --git a/.woodpecker/test.yml b/.woodpecker/test.yml new file mode 100644 index 0000000..c3c4d6b --- /dev/null +++ b/.woodpecker/test.yml @@ -0,0 +1,24 @@ +--- +when: + - event: [pull_request, tag] + - event: [push, manual] + branch: + - ${CI_REPO_DEFAULT_BRANCH} + +steps: + - name: git-spaces + image: quay.io/thegeeklab/alpine-tools + commands: + - git diff-tree --check $(git hash-object -t tree /dev/null) HEAD + + - name: tflint + image: ghcr.io/terraform-linters/tflint + commands: + - tflint --color + + - name: terraform + image: docker.io/jmccann/drone-terraform:8 + settings: + actions: + - validate + tf_version: 1.5.0 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3812eb4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Robert Kaussow + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..56bda42 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +# pve-server-tf + +[![Build Status](https://ci.rknet.org/api/badges/infra/pve-server-tf/status.svg)](https://ci.rknet.org/repos/infra/pve-server-tf) +[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://gitea.rknet.org/infra/pve-server-tf/src/branch/main/LICENSE) + +Terraform module to provision Proxmox VE KVM servers. + +## Usage + +This [Terraform module](https://www.terraform.io/docs/language/modules/syntax.html) is used in our deployment repos to avoid duplicate resource definitions and simplify maintenance. + +## License + +This project is licensed under the MIT License - see the [LICENSE](https://github.com/ansible/galaxy/blob/main/LICENSE) file for details. diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..2879611 --- /dev/null +++ b/main.tf @@ -0,0 +1,103 @@ +resource "proxmox_virtual_environment_vm" "server" { + for_each = { for row in var.server : row.name => row } + + name = "${each.value.name}.${try(each.value.dns_zone, var.server_dns_zone)}" + description = try(each.value.description, null) + tags = concat( + [ + "provisioner_terraform", + "os_${each.value.os}", + "zone_${each.value.zone}" + ], + [for service in try(each.value.services, []) : "service_${service}"], + [for type in try(each.value.types, []) : "type_${type}"], + try(each.value.labels, []) + ) + + node_name = var.pve_node_name + vm_id = each.value.vm_id + on_boot = try(each.value.on_boot, true) + reboot = try(each.value.reboot, false) + scsi_hardware = "virtio-scsi-pci" + keyboard_layout = try(each.value.keyboard_layout, var.server_keyboard_layout) + + agent { + enabled = try(each.value.guest_agent, var.server_guest_agent) + } + + cpu { + type = try(each.value.cpu_type, "x86-64-v2-AES") + cores = try(each.value.cpu_cores, 1) + sockets = try(each.value.cpu_sockets, 1) + } + + memory { + dedicated = try(each.value.memory, 1024) + floating = try(each.value.balloon, true) ? try(each.value.memory, 1024) : 0 + } + + dynamic "disk" { + for_each = concat( + [{ size = 20, backup = true }], + try(each.value.volumes, []) + ) + + content { + interface = "scsi${disk.key}" + datastore_id = try(disk.value.datastore_id, var.server_datastore_id) + path_in_datastore = "vm-${each.value.vm_id}-disk-${disk.key}" + size = disk.value.size + + file_format = "raw" + cache = "none" + ssd = try(disk.value.ssd, false) + discard = "on" + } + } + + network_device { + model = "virtio" + bridge = try(each.value.networks[0].bridge, var.server_network_bridge) + vlan_id = try(each.value.networks[0].vlan_id, null) + } + + operating_system { + type = "l26" + } + + clone { + vm_id = each.value.clone_vm_id + full = try(each.value.clone_full, true) + } + + initialization { + datastore_id = try(each.value.datastore_id, var.server_datastore_id) + + ip_config { + ipv4 { + address = try(each.value.networks[0].ipv4_address, "dhcp") + gateway = try(each.value.networks[0].ipv4_gateway, null) + } + } + + user_account { + keys = var.pve_ssh_keys + username = "root" + } + } +} + +resource "restapi_object" "ucs_server" { + for_each = { for row in var.server : row.name => row } + + path = "/dns/host_record/" + data = jsonencode({ + "position" : var.ucs_zones[try(each.value.dns_zone, var.server_dns_zone)], + "properties" : { + "name" : each.value.name, + "a" : concat( + [for k, v in flatten(proxmox_virtual_environment_vm.server[each.value.name].ipv4_addresses) : v if k != index(proxmox_virtual_environment_vm.server[each.value.name].network_interface_names, "lo")], + ), + } + }) +} diff --git a/outputs.tf b/outputs.tf new file mode 100644 index 0000000..ef90176 --- /dev/null +++ b/outputs.tf @@ -0,0 +1,5 @@ +output "output" { + value = { + for server_key, server in proxmox_virtual_environment_vm.server : server_key => server + } +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..fbf1a8a --- /dev/null +++ b/variables.tf @@ -0,0 +1,69 @@ +// Proxmox VE +# variable "pve_api_url" { +# type = string +# } + +# variable "pve_api_token" { +# type = string +# } + +variable "pve_ssh_keys" { + type = list(string) +} + +variable "pve_node_name" { + type = string +} + +// Cloudflare +variable "cloudflare_api_token" { + type = string +} + +variable "cloudflare_zones" { + type = any +} + +// Univention +variable "ucs_api_url" { + type = string +} + +variable "ucs_api_username" { + type = string +} + +variable "ucs_api_password" { + type = string +} + +variable "ucs_zones" { + type = any +} + +// Module +variable "server" { + type = any + default = [] +} + +variable "server_dns_zone" { + type = string +} + +variable "server_datastore_id" { + type = string +} + +variable "server_network_bridge" { + type = string +} + +variable "server_keyboard_layout" { + type = string +} + +variable "server_guest_agent" { + type = bool + default = false +} diff --git a/versions.tf b/versions.tf new file mode 100644 index 0000000..51691be --- /dev/null +++ b/versions.tf @@ -0,0 +1,13 @@ +terraform { + required_providers { + cloudflare = { + source = "cloudflare/cloudflare" + } + proxmox = { + source = "bpg/proxmox" + } + restapi = { + source = "mastercard/restapi" + } + } +}