Skip to content

Commit

Permalink
Add backend module for z/VM provisioning
Browse files Browse the repository at this point in the history
  • Loading branch information
Eric Bischoff authored and Bischoff committed Nov 24, 2023
1 parent 5f9b205 commit 44ef9d0
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 0 deletions.
75 changes: 75 additions & 0 deletions backend_modules/feilong/README.md
Original file line number Diff line number Diff line change
@@ -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 = "[email protected]"
}
...
```


## 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"
}
...
```
15 changes: 15 additions & 0 deletions backend_modules/feilong/base/main.tf
Original file line number Diff line number Diff line change
@@ -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
}
}
1 change: 1 addition & 0 deletions backend_modules/feilong/base/variables.tf
9 changes: 9 additions & 0 deletions backend_modules/feilong/base/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_version = "1.0.10"
required_providers {
feilong = {
source = "bischoff/feilong"
version = "0.0.2"
}
}
}
107 changes: 107 additions & 0 deletions backend_modules/feilong/host/main.tf
Original file line number Diff line number Diff line change
@@ -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 ]
}
}
1 change: 1 addition & 0 deletions backend_modules/feilong/host/variables.tf
9 changes: 9 additions & 0 deletions backend_modules/feilong/host/versions.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
terraform {
required_version = "1.0.10"
required_providers {
feilong = {
source = "bischoff/feilong"
version = "0.0.2"
}
}
}

0 comments on commit 44ef9d0

Please sign in to comment.