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 26, 2023
1 parent 0a7bafb commit e7e2cc7
Show file tree
Hide file tree
Showing 11 changed files with 243 additions and 8 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"
}
}
}
2 changes: 2 additions & 0 deletions modules/controller/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ module "controller" {
opensuse154arm_sshminion = length(var.opensuse154arm_sshminion_configuration["hostnames"]) > 0 ? var.opensuse154arm_sshminion_configuration["hostnames"][0] : null
opensuse155arm_minion = length(var.opensuse155arm_minion_configuration["hostnames"]) > 0 ? var.opensuse155arm_minion_configuration["hostnames"][0] : null
opensuse155arm_sshminion = length(var.opensuse155arm_sshminion_configuration["hostnames"]) > 0 ? var.opensuse155arm_sshminion_configuration["hostnames"][0] : null
sle15sp3s390_minion = length(var.sle15sp3s390_minion_configuration["hostnames"]) > 0 ? var.sle15sp3s390_minion_configuration["hostnames"][0] : null
sle15sp3s390_sshminion = length(var.sle15sp3s390_sshminion_configuration["hostnames"]) > 0 ? var.sle15sp3s390_sshminion_configuration["hostnames"][0] : null
}


Expand Down
14 changes: 14 additions & 0 deletions modules/controller/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -634,6 +634,20 @@ variable "opensuse155arm_sshminion_configuration" {
}
}

variable "sle15sp3s390_minion_configuration" {
description = "use module.<SLE15SP3S390_MINION>.configuration"
default = {
hostnames = []
}
}

variable "sle15sp3s390_sshminion_configuration" {
description = "use module.<SLE15SP3S390_SSHMINION>.configuration"
default = {
hostnames = []
}
}

variable "additional_repos" {
description = "extra repositories in the form {label = url}, see README_ADVANCED.md"
default = {}
Expand Down
4 changes: 3 additions & 1 deletion salt/controller/bashrc
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export VIRTHOST_KVM_PASSWORD="linux" {% else %}# no KVM host defined {% endif %}
{% if grains.get('additional_network') | default(false, true) %}export PRIVATENET="{{ grains.get('additional_network') }}" {% else %}# no private network defined {% endif %}
{% if grains.get('mirror') | default(false, true) %}export MIRROR="yes" {% else %}# no mirror used {% endif %}

# QAM clients
# BV clients
{% if grains.get('sle11sp4_minion') | default(false, true) %}export SLE11SP4_MINION="{{ grains.get('sle11sp4_minion') }}" {% else %}# no SLE11SP4 minion defined {% endif %}
{% if grains.get('sle11sp4_sshminion') | default(false, true) %}export SLE11SP4_SSHMINION="{{ grains.get('sle11sp4_sshminion') }}" {% else %}# no SLE11SP4 ssh minion defined {% endif %}
{% if grains.get('sle11sp4_client') | default(false, true) %}export SLE11SP4_CLIENT="{{ grains.get('sle11sp4_client') }}" {% else %}# no SLE11SP4 client defined {% endif %}
Expand Down Expand Up @@ -98,6 +98,8 @@ export VIRTHOST_KVM_PASSWORD="linux" {% else %}# no KVM host defined {% endif %}
{% if grains.get('opensuse154arm_sshminion') | default(false, true) %}export OPENSUSE154ARM_SSHMINION="{{ grains.get('opensuse154arm_sshminion') }}" {% else %}# no OPENSUSE154ARM ssh minion defined {% endif %}
{% if grains.get('opensuse155arm_minion') | default(false, true) %}export OPENSUSE155ARM_MINION="{{ grains.get('opensuse155arm_minion') }}" {% else %}# no OPENSUSE155ARM minion defined {% endif %}
{% if grains.get('opensuse155arm_sshminion') | default(false, true) %}export OPENSUSE155ARM_SSHMINION="{{ grains.get('opensuse155arm_sshminion') }}" {% else %}# no OPENSUSE155ARM ssh minion defined {% endif %}
{% if grains.get('sle15sp3s390_minion') | default(false, true) %}export SLE15SP3S390_MINION="{{ grains.get('sle15sp3s390_minion') }}" {% else %}# no SLE15SP3S390 minion defined {% endif %}
{% if grains.get('sle15sp3s390_sshminion') | default(false, true) %}export SLE15SP3S390_SSHMINION="{{ grains.get('sle15sp3s390_sshminion') }}" {% else %}# no SLE15SP3S390 ssh minion defined {% endif %}

# various test suite settings
export GITPROFILES="{{ grains.get('git_profiles_repo') }}"
Expand Down
14 changes: 7 additions & 7 deletions salt/repos/default.sls
Original file line number Diff line number Diff line change
Expand Up @@ -251,18 +251,18 @@ tools_additional_repo:
tools_pool_repo:
pkgrepo.managed:
{% if 'beta' in grains.get('product_version') | default('', true) %}
- baseurl: http://{{ grains.get("mirror") | default("download.suse.de/ibs", true) }}/SUSE/Products/SLE-Manager-Tools/15-BETA/x86_64/product/
- baseurl: http://{{ grains.get("mirror") | default("download.suse.de/ibs", true) }}/SUSE/Products/SLE-Manager-Tools/15-BETA/{{ grains.get("cpuarch") }}/product/
{% else %}
- baseurl: http://{{ grains.get("mirror") | default("download.suse.de/ibs", true) }}/SUSE/Products/SLE-Manager-Tools/15/x86_64/product/
- baseurl: http://{{ grains.get("mirror") | default("download.suse.de/ibs", true) }}/SUSE/Products/SLE-Manager-Tools/15/{{ grains.get("cpuarch") }}/product/
{% endif %}
- refresh: True

tools_update_repo:
pkgrepo.managed:
{% if 'beta' in grains.get('product_version') | default('', true) %}
- baseurl: http://{{ grains.get("mirror") | default("download.suse.de/ibs", true) }}/SUSE/Updates/SLE-Manager-Tools/15-BETA/x86_64/update/
- baseurl: http://{{ grains.get("mirror") | default("download.suse.de/ibs", true) }}/SUSE/Updates/SLE-Manager-Tools/15-BETA/{{ grains.get("cpuarch") }}/update/
{% else %}
- baseurl: http://{{ grains.get("mirror") | default("download.suse.de/ibs", true) }}/SUSE/Updates/SLE-Manager-Tools/15/x86_64/update/
- baseurl: http://{{ grains.get("mirror") | default("download.suse.de/ibs", true) }}/SUSE/Updates/SLE-Manager-Tools/15/{{ grains.get("cpuarch") }}/update/
{% endif %}
- refresh: True
{% else %}
Expand Down Expand Up @@ -379,17 +379,17 @@ os_ltss_repo:

os_pool_repo:
pkgrepo.managed:
- baseurl: http://{{ grains.get("mirror") | default("download.suse.de/ibs", true) }}/SUSE/Products/SLE-Module-Basesystem/15-SP3/x86_64/product/
- baseurl: http://{{ grains.get("mirror") | default("download.suse.de/ibs", true) }}/SUSE/Products/SLE-Module-Basesystem/15-SP3/{{ grains.get("cpuarch") }}/product/
- refresh: True

os_update_repo:
pkgrepo.managed:
- baseurl: http://{{ grains.get("mirror") | default("download.suse.de/ibs", true) }}/SUSE/Updates/SLE-Module-Basesystem/15-SP3/x86_64/update/
- baseurl: http://{{ grains.get("mirror") | default("download.suse.de/ibs", true) }}/SUSE/Updates/SLE-Module-Basesystem/15-SP3/{{ grains.get("cpuarch") }}/update/
- refresh: True

os_ltss_repo:
pkgrepo.managed:
- baseurl: http://{{ grains.get("mirror") | default("download.suse.de", true) }}/ibs/SUSE/Updates/SLE-Product-SLES/15-SP3-LTSS/x86_64/update/
- baseurl: http://{{ grains.get("mirror") | default("download.suse.de", true) }}/ibs/SUSE/Updates/SLE-Product-SLES/15-SP3-LTSS/{{ grains.get("cpuarch") }}/update/

{% endif %} {# '15.3' == grains['osrelease'] #}

Expand Down

0 comments on commit e7e2cc7

Please sign in to comment.