From 44ef9d04184c9818d7e310fecc82331131b839c5 Mon Sep 17 00:00:00 2001 From: Eric Bischoff Date: Wed, 22 Nov 2023 18:16:02 +0100 Subject: [PATCH] Add backend module for z/VM provisioning --- backend_modules/feilong/README.md | 75 +++++++++++++++ backend_modules/feilong/base/main.tf | 15 +++ backend_modules/feilong/base/variables.tf | 1 + backend_modules/feilong/base/versions.tf | 9 ++ backend_modules/feilong/host/main.tf | 107 ++++++++++++++++++++++ backend_modules/feilong/host/variables.tf | 1 + backend_modules/feilong/host/versions.tf | 9 ++ 7 files changed, 217 insertions(+) create mode 100644 backend_modules/feilong/README.md create mode 100644 backend_modules/feilong/base/main.tf create mode 120000 backend_modules/feilong/base/variables.tf create mode 100644 backend_modules/feilong/base/versions.tf create mode 100644 backend_modules/feilong/host/main.tf create mode 120000 backend_modules/feilong/host/variables.tf create mode 100644 backend_modules/feilong/host/versions.tf diff --git a/backend_modules/feilong/README.md b/backend_modules/feilong/README.md new file mode 100644 index 000000000..3a424c93b --- /dev/null +++ b/backend_modules/feilong/README.md @@ -0,0 +1,75 @@ +# Feilong-specific configuration + +## Overview + +Base Module currrently does not create any resources, but is used to define shared variables. + +Host Module currently creates for each host: + +- a set of cloud-init parameters, that will be stored into a local file in `/tmp` directory; this file will then be uploaded by Feilong at VM deployment time +- a z/VM guest virtual machine. + + +## Prerequisites + +You will need: + +- a s/390 mainframe running z/VM inside one of its LPARs +- a Feilong connector, running on a Linux system inside a z/VM guest in that LPAR +- to have a pair of openSSH keys created for user `zvmsdk` on that Linux system +- to grant the Feilong connector SSH access to your local workstation so it can download files + +The Feilong connector can either be deployed standalone, following these [instructions](https://cloudlib4zvm.readthedocs.io/en/latest/quickstart.html#installation), or be part of a larger [IBM Cloud Infrastructure Center](https://www.ibm.com/products/cloud-infrastructure-center) (CIC). + +You can grant access to the Feilong connector to your local account by adding the public key of `zvmsdk` user into your `~/.ssh/autorized_keys` file. + +An usage example follows: + +```hcl-terraform +... +provider "feilong" { + connector = "feilong.example.org" + local_user = "johndoe@test.example.org" +} +... +``` + + +## Select Feilong backend to be used + +If you want a pure s/390 deployment, create a symbolic link to the `feilong` backend module directory inside the `modules` directory: `ln -sfn ../backend_modules/feilong modules/backend`. + +If you rather want to mix it with e.g. the libvirt module, just call directly from your `main.tf` file the `base` and `host` backend modules. + + +## Feilong backend specific variables + +Most modules have configuration settings specific to the Feilong backend, those are set via the `provider_settings` map variable. They are all described below. + +### Base Module + +| Variable name | Type | Default value | Description | +|--------------------------|--------|-----------------|-------------------------------------------------------------------------------------------------------------------------| +| key_file | string | `~/.ssh/id_rsa` | path to private SSH key file used for provisioning | + +### Host Module + +| Variable name | Type | Default value | Description | +|--------------------------|--------|-----------------|-------------------------------------------------------------------------------------------------------------------------| +| userid | string | `null` | system name for z/VM (8 characters maximum, all caps) | +| memory | string | `2G` | amount of VM "storage", as an integer followed by an unit: B, K, M, G | +| vcpu | number | `1` | number of virtual CPUs assigned to the VM | +| mac | string | `null` | MAC address as 6 hexadecimal digits separed by colons; beware the first 3 bytes might be replaced by Feilong's default | +| ssh_user | string | `root` | system user to connect to via SSH for provisioning | + +An example follows: + +```hcl-terraform +... +provider_settings = { + userid = "S15SP3" + mac = "02:3a:fc:44:55:66" + ssh_user = "sles" +} +... +``` diff --git a/backend_modules/feilong/base/main.tf b/backend_modules/feilong/base/main.tf new file mode 100644 index 000000000..2288f0653 --- /dev/null +++ b/backend_modules/feilong/base/main.tf @@ -0,0 +1,15 @@ +locals { + name_prefix = var.name_prefix + domain = var.domain + ssh_key_path = var.ssh_key_path + key_file = lookup(var.provider_settings, "key_file", "~/.ssh/id_rsa") +} + +output "configuration" { + value = { + name_prefix = local.name_prefix + domain = local.domain + ssh_key_path = local.ssh_key_path + key_file = local.key_file + } +} diff --git a/backend_modules/feilong/base/variables.tf b/backend_modules/feilong/base/variables.tf new file mode 120000 index 000000000..131e60a3a --- /dev/null +++ b/backend_modules/feilong/base/variables.tf @@ -0,0 +1 @@ +../../null/base/variables.tf \ No newline at end of file diff --git a/backend_modules/feilong/base/versions.tf b/backend_modules/feilong/base/versions.tf new file mode 100644 index 000000000..4d935b1ee --- /dev/null +++ b/backend_modules/feilong/base/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = "1.0.10" + required_providers { + feilong = { + source = "bischoff/feilong" + version = "0.0.2" + } + } +} diff --git a/backend_modules/feilong/host/main.tf b/backend_modules/feilong/host/main.tf new file mode 100644 index 000000000..3ee1859d9 --- /dev/null +++ b/backend_modules/feilong/host/main.tf @@ -0,0 +1,107 @@ +locals { + name_prefix = var.base_configuration["name_prefix"] + domain = var.base_configuration["domain"] + ssh_key_path = var.base_configuration["ssh_key_path"] + provider_settings = merge({ + userid = null + memory = "2G" + vcpu = 1 + mac = null + ssh_user = "root" + key_file = var.base_configuration["key_file"] + }, + var.provider_settings) +} + +resource "feilong_cloudinit_params" "s390_params" { + name = "${local.name_prefix}${var.name}" + + hostname = "${local.name_prefix}${var.name}.${local.domain}" + public_key = trimspace(file(local.ssh_key_path)) +} + +resource "feilong_guest" "s390_guest" { + depends_on = [ feilong_cloudinit_params.s390_params ] + + name = "${local.name_prefix}${var.name}" + + memory = local.provider_settings["memory"] + disk = "20G" + vcpus = local.provider_settings["vcpu"] + image = var.image + userid = local.provider_settings["userid"] + mac = local.provider_settings["mac"] + + cloudinit_params = feilong_cloudinit_params.s390_params.file +} + +resource "null_resource" "provisioning" { + depends_on = [ feilong_guest.s390_guest ] + + triggers = { + } + + connection { + host = feilong_guest.s390_guest.ip_address + private_key = file(local.provider_settings["key_file"]) + user = local.provider_settings["ssh_user"] + } + + provisioner "file" { + source = "salt" + destination = "/tmp" + } + + provisioner "file" { + content = yamlencode( + { + hostname = "${local.name_prefix}${var.name}" + domain = local.domain + use_avahi = false + provider = "feilong" + roles = var.roles + use_os_released_updates = var.use_os_released_updates + additional_repos = var.additional_repos + additional_repos_only = var.additional_repos_only + additional_certs = var.additional_certs + additional_packages = var.additional_packages + install_salt_bundle = var.install_salt_bundle + swap_file_size = var.swap_file_size + authorized_keys = var.ssh_key_path + gpg_keys = var.gpg_keys + connect_to_base_network = true + connect_to_additional_network = false + ipv6 = var.ipv6 + + // These should be defined in a "sumaform module", but we cannot use sumaform modules, + // because "backend" symbolic link probably points to a different backend module :-( + timezone = "Europe/Berlin" + use_ntp = true + }) + destination = "/tmp/grains" + } + + provisioner "remote-exec" { + inline = [ + "sudo bash /tmp/salt/wait_for_salt.sh", + ] + } + + provisioner "remote-exec" { + inline = [ + "sudo rm -rf /root/salt", + "sudo mv /tmp/salt /root", + "sudo bash /root/salt/first_deployment_highstate.sh" + ] + } +} + +output "configuration" { + depends_on = [ feilong_guest.s390_guest, null_resource.provisioning ] + value = { + ids = [ feilong_guest.s390_guest.userid ] + hostnames = [ feilong_cloudinit_params.s390_params.hostname ] + macaddrs = [ feilong_guest.s390_guest.mac_address ] + ipaddrs = [ feilong_guest.s390_guest.ip_address ] + } +} diff --git a/backend_modules/feilong/host/variables.tf b/backend_modules/feilong/host/variables.tf new file mode 120000 index 000000000..31254464c --- /dev/null +++ b/backend_modules/feilong/host/variables.tf @@ -0,0 +1 @@ +../../null/host/variables.tf \ No newline at end of file diff --git a/backend_modules/feilong/host/versions.tf b/backend_modules/feilong/host/versions.tf new file mode 100644 index 000000000..4d935b1ee --- /dev/null +++ b/backend_modules/feilong/host/versions.tf @@ -0,0 +1,9 @@ +terraform { + required_version = "1.0.10" + required_providers { + feilong = { + source = "bischoff/feilong" + version = "0.0.2" + } + } +}