Skip to content

Commit 0e89860

Browse files
authored
Merge pull request #37 from bikashrc25/portworx
Add support for Portworx and future storage modules
2 parents 473f1fc + c02b703 commit 0e89860

File tree

11 files changed

+326
-1
lines changed

11 files changed

+326
-1
lines changed

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,24 @@ metal_project_id = "YOUR-PROJECT-ID"
227227
## Google Anthos Documentation
228228
Once Anthos is deployed on Equinix Metal, all of the documentation for using Google Anthos is located on the [Anthos Documentation Page](https://cloud.google.com/anthos/docs).
229229

230+
## Storage Providers
231+
232+
Storage providers are made available through optional storage modules. These storage providers include CSI (Container Native Storage) `StorageClasses`.
233+
234+
Changing or disabling a storage provider is not currently supported.
235+
236+
To enable a storage module, set the `storage_module` variable to the name of the name of the included module.
237+
238+
* `portworx`: To enable the Pure Storage Portworx installation, use the following settings in `terraform.tfvars`:
239+
240+
```hcl
241+
storage_module = "portworx"
242+
storage_options = {
243+
# portworx_version = "2.6"
244+
# portworx_license = "c0ffe-fefe-activation-123"
245+
}
246+
```
247+
248+
When enabled, Portworx will manage the local disks attached to each worker node, providing a fault tolerant distributed storage solution.
249+
250+
[Read more about the Portworx module](modules/portworx/README).

main.tf

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,13 @@ data "template_file" "deploy_anthos_cluster" {
145145
}
146146
}
147147

148+
data "template_file" "pre_reqs_worker" {
149+
template = file("templates/pre_reqs_worker.sh")
150+
vars = {
151+
operating_system = var.operating_system
152+
}
153+
}
154+
148155
resource "null_resource" "prep_anthos_cluster" {
149156
depends_on = [
150157
google_project_service.enabled-apis
@@ -206,6 +213,9 @@ data "template_file" "create_cluster" {
206213
}
207214
}
208215

216+
// Initialize Anthos on the first control plane node.
217+
// This will also trigger installs (including apt)
218+
// on the worker nodes.
209219
resource "null_resource" "deploy_anthos_cluster" {
210220
depends_on = [
211221
null_resource.prep_anthos_cluster,
@@ -420,3 +430,52 @@ resource "null_resource" "install_kube_vip_daemonset" {
420430
}
421431
}
422432

433+
resource "null_resource" "worker_pre_reqs" {
434+
count = var.worker_count
435+
depends_on = [
436+
null_resource.deploy_anthos_cluster,
437+
]
438+
439+
connection {
440+
type = "ssh"
441+
user = "root"
442+
private_key = chomp(tls_private_key.ssh_key_pair.private_key_pem)
443+
host = element(metal_device.worker_nodes.*.access_public_ipv4, count.index)
444+
}
445+
446+
provisioner "remote-exec" {
447+
inline = ["mkdir -p /root/bootstrap/"]
448+
}
449+
450+
# Unless /root/bootstrap/ is created in advance, this will be
451+
# copied to /root/bootstrap (file)
452+
# https://github.com/hashicorp/terraform/issues/16330
453+
provisioner "file" {
454+
content = data.template_file.pre_reqs_worker.rendered
455+
destination = "/root/bootstrap/pre_reqs_worker.sh"
456+
}
457+
458+
provisioner "remote-exec" {
459+
inline = ["bash /root/bootstrap/pre_reqs_worker.sh"]
460+
}
461+
}
462+
463+
module "storage" {
464+
source = "./modules/storage"
465+
466+
depends_on = [
467+
null_resource.add_kubelet_flags_to_workers,
468+
]
469+
470+
ssh = {
471+
host = metal_device.control_plane.0.access_public_ipv4
472+
private_key = chomp(tls_private_key.ssh_key_pair.private_key_pem)
473+
user = "root"
474+
kubeconfig = "/root/baremetal/bmctl-workspace/${local.cluster_name}/${local.cluster_name}-kubeconfig"
475+
worker_addresses = metal_device.worker_nodes.*.access_public_ipv4
476+
}
477+
478+
cluster_name = local.cluster_name
479+
storage_module = var.storage_module
480+
storage_options = var.storage_options
481+
}

modules/portworx/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Pure Storage Portworx installation
2+
3+
Portworx by Pure Storage is a distributed and high available data storage that takes advantage of the local and attached storage provided on each Equinix Metal device. Portworx includes a [Container Storage Interface (CSI)](https://kubernetes-csi.github.io/docs/) driver.
4+
5+
Portworx differentiates between device disks using priority labels that can be applied to create distinct `StorageClasses`. See [Portworx: Dynamic Provisioning](https://docs.portworx.com/portworx-install-with-kubernetes/storage-operations/create-pvcs/dynamic-provisioning/) for more details.
6+
7+
Login to any one of the Anthos cluster nodes and run `pxctl status` to check the state of the Portworx services.
8+
9+
You can also use the Kubernetes API to check the status:
10+
11+
```sh
12+
kubectl get pods -lapp=portworx -n kube-system
13+
```
14+
15+
Portworx logs can be viewed by running:
16+
17+
```sh
18+
kubectl logs -lapp=portworx -n kube-system --all-containers
19+
```
20+
21+
By default, Portworx 2.6 is installed in the Anthos Cluster. The version of Portworx can be changed using the `portworx_version` variable.
22+
23+
## Licensing
24+
25+
Portworx is installed with a Trial license. To continue use at the end of the trial period, you will need a Portworx Enterprise Metal license.
26+
27+
More information about these licenses, their restrictions and enablement can be found at <https://docs.portworx.com/reference/knowledge-base/px-licensing/>.
28+
29+
To active the Portworx license through this module:
30+
31+
* Set the `portworx_license` variable to your license key
32+
* Run `terraform apply`
33+
34+
**Note**: The `portworx_license` variable can not be set and defined before the Portworx installation is ready. This takes about 15 minutes today. If you attempt to provide the license too early the `terraform apply` will fail, affecting only this licensing task. A subsequent and successful `terraform apply` will be needed to correct the licensing.
35+
36+
Alternatively, `ssh` into any worker node and run `/opt/pwx/bin/pxctl license activate _key_`.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env bash
2+
createlvm=true
3+
deletelvm=false
4+
dsksize="0"
5+
6+
function largest_free_disk {
7+
lsblk -f -d -b -n -oNAME,SIZE | while read disk size; do
8+
# ignore disks with filesystems
9+
if ! lsblk -f -b -n -oNAME,SIZE,FSTYPE -i /dev/$disk | egrep "xfs|ext3|ext4|btrfs|sr0" >/dev/null; then
10+
echo -en "$disk $size"
11+
fi
12+
done | sort -n -k2 | head -n1 | cut -f1 -d" "
13+
}
14+
15+
16+
dskname=$(largest_free_disk)
17+
echo "Will use $dskname for Portworx KVDB LVM by running the following commands(will only run if createlvm=true)"
18+
dev="/dev/$dskname"
19+
echo "pvcreate $dev"
20+
echo "vgcreate pwx_vg $dev"
21+
echo "lvcreate -l 100%FREE -n pwxkvdb pwx_vg"
22+
if $createlvm; then
23+
pvcreate $dev
24+
vgcreate pwx_vg $dev
25+
lvcreate -l 100%FREE -n pwxkvdb pwx_vg
26+
fi
27+
if $deletelvm; then
28+
lvremove /dev/pwx_vg/pwxkvdb
29+
vgremove pwx_vg
30+
pvremove $dev
31+
wipefs -a $dev
32+
fi

modules/portworx/main.tf

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
resource "null_resource" "worker_disks" {
2+
count = length(var.ssh.worker_addresses)
3+
4+
connection {
5+
type = "ssh"
6+
user = var.ssh.user
7+
private_key = var.ssh.private_key
8+
host = var.ssh.worker_addresses[count.index]
9+
}
10+
11+
provisioner "remote-exec" {
12+
inline = ["mkdir -p /root/bootstrap/"]
13+
}
14+
15+
provisioner "file" {
16+
source = "${path.module}/assets/portworx_disk_setup.sh"
17+
destination = "/root/bootstrap/portworx_disk_setup.sh"
18+
19+
}
20+
provisioner "remote-exec" {
21+
inline = [
22+
"bash /root/bootstrap/portworx_disk_setup.sh"
23+
]
24+
}
25+
}
26+
27+
locals {
28+
portworx_version = try(length(var.portworx_version) ? var.portworx_version
29+
: var.latest_portworx_version, var.latest_portworx_version)
30+
}
31+
32+
resource "null_resource" "install_portworx" {
33+
depends_on = [
34+
null_resource.worker_disks
35+
]
36+
connection {
37+
type = "ssh"
38+
user = var.ssh.user
39+
private_key = var.ssh.private_key
40+
host = var.ssh.host
41+
}
42+
43+
provisioner "remote-exec" {
44+
inline = [
45+
"VER=$(kubectl version --short | awk -Fv '/Server Version: / {print $3}')",
46+
"URL='https://install.portworx.com/${local.portworx_version}?mc=false&kbver='$VER'&b=true&j=auto&kd=${urlencode("/dev/pwx_vg/pwxkvdb")}&c=${var.cluster_name}&stork=true&st=k8s&pp=IfNotPresent'",
47+
"kubectl --kubeconfig ${var.ssh.kubeconfig} apply -f $URL"
48+
]
49+
}
50+
}
51+
52+
resource "null_resource" "license_portworx" {
53+
count = length(var.portworx_license) > 0 ? 1 : 0
54+
55+
depends_on = [
56+
null_resource.install_portworx
57+
]
58+
connection {
59+
type = "ssh"
60+
user = var.ssh.user
61+
private_key = var.ssh.private_key
62+
host = var.ssh.worker_addresses[0]
63+
}
64+
65+
provisioner "remote-exec" {
66+
inline = [
67+
"/opt/pwx/bin/pxctl license activate ${var.portworx_license}"
68+
]
69+
}
70+
}

modules/portworx/variables.tf

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
variable "portworx_version" {
2+
type = string
3+
description = "The version of Portworx to install (latest_portworx_version will be used if not set)"
4+
default = ""
5+
}
6+
7+
variable "portworx_license" {
8+
type = string
9+
description = "License key for Portworx. A Trial license is used by default. Setting this value before Portworx is installed and ready will result in a failed `apply` that can be corrected by applying again after the Portworx install has completed."
10+
default = ""
11+
}
12+
13+
variable "latest_portworx_version" {
14+
type = string
15+
description = "The version of Portworx to install"
16+
default = "2.6"
17+
}
18+
19+
variable "cluster_name" {
20+
type = string
21+
description = "Name of the cluster"
22+
}
23+
24+
variable "ssh" {
25+
description = "SSH options for the storage provider including SSH details to access the control plane including the remote path to the kubeconfig file and a list of worker addresses"
26+
27+
type = object({
28+
host = string
29+
private_key = string
30+
user = string
31+
kubeconfig = string
32+
worker_addresses = list(string)
33+
})
34+
}

modules/storage/main.tf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module "portworx" {
2+
count = var.storage_module == "portworx" ? 1 : 0
3+
source = "../portworx"
4+
portworx_version = try(var.storage_options.portworx_version, "")
5+
portworx_license = try(var.storage_options.portworx_license, "")
6+
ssh = var.ssh
7+
cluster_name = var.cluster_name
8+
}

modules/storage/variables.tf

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
variable "storage_module" {
2+
description = "The name of the Storage provider module (ex. \"portworx\")"
3+
default = ""
4+
}
5+
6+
variable "storage_options" {
7+
type = any
8+
description = "Options for the Storage provider module. Option names can be found in the documentation for each module and are prefixed with the vendor name (\"portworx_version\")"
9+
default = {}
10+
}
11+
12+
variable "cluster_name" {
13+
type = string
14+
description = "Name of the cluster"
15+
}
16+
17+
variable "ssh" {
18+
description = "SSH options for the storage provider including SSH details to access the control plane including the remote path to the kubeconfig file and a list of worker addresses."
19+
20+
type = object({
21+
host = string
22+
private_key = string
23+
user = string
24+
kubeconfig = string
25+
worker_addresses = list(string)
26+
})
27+
}

templates/pre_reqs.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ EOM
5454

5555

5656
function unknown_os {
57-
echo "I don't konw who I am" > /root/who_am_i.txt
57+
echo "I don't know who I am" > /root/who_am_i.txt
5858
}
5959

6060
if [ "$${OS:0:6}" = "centos" ] || [ "$${OS:0:4}" = "rhel" ]; then

templates/pre_reqs_worker.sh

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#!/usr/bin/env bash
2+
OS='${operating_system}'
3+
4+
function ubuntu_pre_reqs {
5+
# Install Docker
6+
export DEBIAN_FRONTEND=noninteractive
7+
sudo apt-get update -qy
8+
sudo apt-get install -qy lvm2
9+
}
10+
11+
12+
function rhel_pre_reqs {
13+
sudo dnf install lvm2 -y
14+
}
15+
16+
17+
function unknown_os {
18+
echo "I don't know who I am" > /root/who_am_i.txt
19+
}
20+
21+
if [ "$${OS:0:6}" = "centos" ] || [ "$${OS:0:4}" = "rhel" ]; then
22+
rhel_pre_reqs
23+
elif [ "$${OS:0:6}" = "ubuntu" ]; then
24+
ubuntu_pre_reqs
25+
else
26+
unknown_os
27+
fi

0 commit comments

Comments
 (0)