From d80830f8d31c1b1c7ad7be0a9bee0517338e0757 Mon Sep 17 00:00:00 2001 From: josiah Date: Fri, 28 Jul 2023 09:59:41 -0500 Subject: [PATCH] Initial terraform commit. Create 2 different subfolders: - jowj dot net owns / will own DNS for jowj.net and its subdomains - Bikeshed owns my provisioning VMs against my proxmox cluster env_creds.sh is just a simple way to export secrets from `pass` to my local environment. --- terraform/bikeshed/.terraform.lock.hcl | 23 +++++++++ terraform/bikeshed/main.tf | 65 ++++++++++++++++++++++++++ terraform/bikeshed/vars.tf | 17 +++++++ terraform/env_creds.sh | 5 ++ terraform/jowj_dot_net/main.tf | 6 +++ terraform/jowj_dot_net/provider.tf | 12 +++++ terraform/jowj_dot_net/vars.tf | 5 ++ terraform/readme.org | 15 ++++++ 8 files changed, 148 insertions(+) create mode 100644 terraform/bikeshed/.terraform.lock.hcl create mode 100644 terraform/bikeshed/main.tf create mode 100644 terraform/bikeshed/vars.tf create mode 100644 terraform/env_creds.sh create mode 100644 terraform/jowj_dot_net/main.tf create mode 100644 terraform/jowj_dot_net/provider.tf create mode 100644 terraform/jowj_dot_net/vars.tf create mode 100644 terraform/readme.org diff --git a/terraform/bikeshed/.terraform.lock.hcl b/terraform/bikeshed/.terraform.lock.hcl new file mode 100644 index 0000000..7b07aa1 --- /dev/null +++ b/terraform/bikeshed/.terraform.lock.hcl @@ -0,0 +1,23 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/telmate/proxmox" { + version = "2.7.4" + constraints = "2.7.4" + hashes = [ + "h1:ivNrl7WU2BJwIKmB1lLr70+GtXBCfzW+K5tvNpYy454=", + "zh:3c2163b167d1e342e1683015cd08c70838d1c631b8e374ac6f86ca2c41271a8c", + "zh:453596419e07cd0c41f5f58dd7775664fa685de403e9776197b1502e79bf3814", + "zh:492045cf7859bc31a57730b876dcc29d902a24d543a30a67f34b0ee2b4a71a33", + "zh:4d284e6b9b2bb5892027fb03f020fb4b60ff9fd4b209e37233ca95bbc439ae3c", + "zh:57884f06d1682df2dfcfbaf22a715ac0efccea1f17cdb2e18a16e91182e609fe", + "zh:6c47e8a1b95d30a4d6f81bb53e07cbd70f7fd69ac762454ec101fd175bb81ffc", + "zh:75d10399da8161f5229ffb0ae657dd0f1627399033a12b28a9ea2237fca883cc", + "zh:825be601b3766a6d1dd889104c8ae69db71bc627465fecdf4265315850c5abc6", + "zh:954560596c674fb6aee1dcb5441ec6bb0ad7668cf9d5503d803c6d6f66d0ca2f", + "zh:ab2403718bfdf50470034fe677de735a2d3635a8e24a6816e0fdf370f28f08ba", + "zh:e02854a7c7919abde89d03a4e2b9ccea9780cdd944cd612f5d06e2e99ff946d2", + "zh:f85a8cbb5a96f88e721767e7e68fc86254285a4cfed12704f3f467463a24fe08", + "zh:fe8e21b717f4a6423879bdd3188aee37e4d4daa3a5e35450e414da49fb4f2fa7", + ] +} diff --git a/terraform/bikeshed/main.tf b/terraform/bikeshed/main.tf new file mode 100644 index 0000000..af7a250 --- /dev/null +++ b/terraform/bikeshed/main.tf @@ -0,0 +1,65 @@ +terraform { + required_providers { + proxmox = { + source = "telmate/proxmox" + version = "2.7.4" + } + } +} + +provider "proxmox" { + # url is the hostname (FQDN if you have one) for the proxmox host you'd like to connect to to issue the commands. my proxmox host is 'prox-1u'. Add /api2/json at the end for the API + pm_api_url = "https://192.168.1.230:8006/api2/json" + # api token id is in the form of: @pam! + pm_api_token_id = var.PM_API_TOKEN_ID + # this is the full secret wrapped in quotes. + pm_api_token_secret = var.PM_API_TOKEN_SECRET + # leave tls_insecure set to true unless you have your proxmox SSL certificate situation fully sorted out (if you do, you will know) + pm_tls_insecure = true +} +# resource is formatted to be "[type]" "[entity_name]" so in this case +# we are looking to create a proxmox_vm_qemu entity named test_server +resource "proxmox_vm_qemu" "test_server" { + count = 1 # just want 1 for now, set to 0 and apply to destroy VM + name = "test-vm-${count.index + 1}" #count.index starts at 0, so + 1 means this VM will be named test-vm-1 in proxmox + # this now reaches out to the vars file. I could've also used this var above in the pm_api_url setting but wanted to spell it out up there. target_node is different than api_url. target_node is which node hosts the template and thus also which node will host the new VM. it can be different than the host you use to communicate with the API. the variable contains the contents "prox-1u" + target_node = var.proxmox_host + clone = var.template_name + # basic VM settings here. agent refers to guest agent + agent = 1 + os_type = "debian" + cores = 2 + sockets = 1 + cpu = "host" + memory = 2048 + scsihw = "virtio-scsi-pci" + bootdisk = "scsi0" + disk { + slot = 0 + # set disk size here. leave it small for testing because expanding the disk takes time. + size = "20G" + type = "scsi" + storage = "sainthood-cifs" + iothread = 0 + } + + # if you want two NICs, just copy this whole network section and duplicate it + network { + model = "virtio" + bridge = "vmbr0" + } + # not sure exactly what this is for. presumably something about MAC addresses and ignore network changes during the life of the VM + lifecycle { + ignore_changes = [ + network, + ] + } + + # the ${count.index + 1} thing appends text to the end of the ip address + # in this case, since we are only adding a single VM, the IP will + # be 10.98.1.91 since count.index starts at 0. this is how you can create + # multiple VMs and have an IP assigned to each (.91, .92, .93, etc.) + ipconfig0 = "ip=10.98.1.9${count.index + 1}/24,gw=10.98.1.1" + + # sshkeys set using variables. the variable contains the text of the key. +} diff --git a/terraform/bikeshed/vars.tf b/terraform/bikeshed/vars.tf new file mode 100644 index 0000000..e596fd7 --- /dev/null +++ b/terraform/bikeshed/vars.tf @@ -0,0 +1,17 @@ +variable "proxmox_host" { + default = "demiurge" +} +variable "template_name" { + default = "debian-template" +} + +variable "PM_API_TOKEN_ID" { + description = "API Token ID for proxmox management." + type = string + sensitive = true +} +variable "PM_API_TOKEN_SECRET" { + description = "Secret for prooxmox management." + type = string + sensitive = true +} diff --git a/terraform/env_creds.sh b/terraform/env_creds.sh new file mode 100644 index 0000000..0e80f9a --- /dev/null +++ b/terraform/env_creds.sh @@ -0,0 +1,5 @@ +#!/bin/sh +# sets up env vars needed for configuring proxmox / terraform +export TF_VAR_PM_API_TOKEN_ID=$(pass pm_api_token_id) +export TF_VAR_PM_API_TOKEN_SECRET=$(pass pm_api_token_secret) +export TF_VAR_DO_PAT=$(pass do_pat) diff --git a/terraform/jowj_dot_net/main.tf b/terraform/jowj_dot_net/main.tf new file mode 100644 index 0000000..e02a914 --- /dev/null +++ b/terraform/jowj_dot_net/main.tf @@ -0,0 +1,6 @@ +resource "digitalocean_domain" "default" { + name = "jowj.net" + ip_address = digitalocean_loadbalancer.www-lb.ip +} + + diff --git a/terraform/jowj_dot_net/provider.tf b/terraform/jowj_dot_net/provider.tf new file mode 100644 index 0000000..8c822b0 --- /dev/null +++ b/terraform/jowj_dot_net/provider.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + digitalocean = { + source = "digitalocean/digitalocean" + version = "~> 2.0" + } + } +} + +provider "digitalocean" { + token = var.DO_PAT +} diff --git a/terraform/jowj_dot_net/vars.tf b/terraform/jowj_dot_net/vars.tf new file mode 100644 index 0000000..ddc1be0 --- /dev/null +++ b/terraform/jowj_dot_net/vars.tf @@ -0,0 +1,5 @@ +variable "DO_PAT" { + description = "Personal access token for DO." + type = string + sensitive = true +} diff --git a/terraform/readme.org b/terraform/readme.org new file mode 100644 index 0000000..4fe6d5c --- /dev/null +++ b/terraform/readme.org @@ -0,0 +1,15 @@ +* Overview +The TF module of ~ADC~ inits machine creation in ~Bikeshed~, my local proxmox cluster, and configures DNS for my projects. Or at least, that's the goal. Right now i'm mostly just experimenting with it. + +The idea is to keep ansible for configuration and use TF for machine creation / API communication. + +* Using this +- Install ~Terraform~ +- Move into the directory related to what you want to work on +- ~terraform plan~ +- ~terraform apply~ + +* Stuff to figure out +- State. Using local tf state is mostly reasonable for a personal project, but since I want it to host more of my infra in general I may need to come up with a better solution. Unfortunately, tf state includes secrets for some fucking reason, and that means I need to be careful about where I put the dumb thing. +- Importing. Right now, resources exist outside the context of TF, and the story for getting things like DNS moved to TF is fucking awful, somehow? why does this suck so bad. +