commit
3eb11f69fd
23 changed files with 1197 additions and 0 deletions
@ -0,0 +1,7 @@ |
|||
*.lock.hcl |
|||
*.tfstate |
|||
*.backup |
|||
.terraform |
|||
.vscode |
|||
terraform.tfvars |
|||
install-config.yaml |
|||
@ -0,0 +1,199 @@ |
|||
# OpenShift 4 Installation |
|||
|
|||
## Pre-requisites |
|||
|
|||
### On your local machine |
|||
|
|||
Install Terraform. |
|||
|
|||
```sh |
|||
cat > hashicorp.repo <<"EOF" |
|||
[hashicorp] |
|||
name=Hashicorp Stable - $basearch |
|||
baseurl=https://rpm.releases.hashicorp.com/RHEL/8/$basearch/stable |
|||
enabled=1 |
|||
gpgcheck=1 |
|||
gpgkey=https://rpm.releases.hashicorp.com/gpg |
|||
EOF |
|||
sudo dnf config-manager --add-repo hashicorp.repo |
|||
sudo dnf -y install terraform |
|||
``` |
|||
|
|||
Install the libvirt terraform provider. |
|||
|
|||
```sh |
|||
curl -Lo /tmp/libvirt-provider.tgz https://github.com/dmacvicar/terraform-provider-libvirt/releases/download/v0.6.3/terraform-provider-libvirt-0.6.3+git.1604843676.67f4f2aa.Fedora_32.x86_64.tar.gz |
|||
mkdir -p ~/.terraform.d/plugins/registry.terraform.io/dmacvicar/libvirt/0.6.3/linux_amd64 |
|||
tar xvf /tmp/libvirt-provider.tgz -C ~/.terraform.d/plugins/registry.terraform.io/dmacvicar/libvirt/0.6.3/linux_amd64 |
|||
``` |
|||
|
|||
Install the Gandi terraform provider. |
|||
|
|||
```sh |
|||
git clone https://github.com/go-gandi/terraform-provider-gandi |
|||
cd terraform-provider-gandi |
|||
make |
|||
make install |
|||
``` |
|||
|
|||
### On the hypervisor |
|||
|
|||
```sh |
|||
curl https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/4.7/4.7.0/rhcos-4.7.0-x86_64-qemu.x86_64.qcow2.gz |gunzip -c > /var/lib/libvirt/images/rhcos-4.7.0-x86_64-qemu.x86_64.qcow2 |
|||
curl -Lo /var/lib/libvirt/images/centos-stream-8.qcow2 http://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-20210210.0.x86_64.qcow2 |
|||
``` |
|||
|
|||
## Install |
|||
|
|||
Define the cluster name and the bastion. |
|||
|
|||
```sh |
|||
cluster=ocp4 |
|||
bastion=nicolas@hp-ml350.itix.fr |
|||
``` |
|||
|
|||
Install **openshift-installer** and **oc** on the bastion. |
|||
|
|||
```sh |
|||
ssh -A "$bastion" curl -Lo /tmp/openshift-installer.tgz https://mirror.openshift.com/pub/openshift-v4/clients/ocp/latest-4.7/openshift-install-linux.tar.gz |
|||
ssh -A "$bastion" sudo tar zxvf /tmp/openshift-installer.tgz -C /usr/local/bin openshift-install |
|||
ssh -A "$bastion" curl -Lo /tmp/oc.tgz https://mirror.openshift.com/pub/openshift-v4/clients/ocp/latest-4.7/openshift-client-linux.tar.gz |
|||
ssh -A "$bastion" sudo tar zxvf /tmp/oc.tgz -C /usr/local/bin oc kubectl |
|||
``` |
|||
|
|||
Create the cluster configuration files. |
|||
|
|||
```sh |
|||
mkdir "$cluster" |
|||
cp install-config.yaml.sample "$cluster/install-config.yaml" |
|||
openshift-install create manifests --dir="$cluster" |
|||
openshift-install create ignition-configs --dir="$cluster" |
|||
``` |
|||
|
|||
Customize the terraform variables. |
|||
|
|||
```sh |
|||
cat > terraform.tfvars <<EOF |
|||
base_domain = "itix.xyz" |
|||
external_mac_address = "02:00:00:00:00:04" |
|||
public_cluster_ip = "90.79.1.247" |
|||
cluster_name = "$cluster" |
|||
EOF |
|||
``` |
|||
|
|||
Apply the terraform plan. |
|||
|
|||
```sh |
|||
terraform apply |
|||
``` |
|||
|
|||
Copy the cluster definition on the bastion and run the bootstrap process from there. |
|||
|
|||
```sh |
|||
scp -r "$cluster" "$bastion:'$cluster'" |
|||
ssh -A "$bastion" openshift-install --dir="$cluster" wait-for bootstrap-complete --log-level=info |
|||
``` |
|||
|
|||
Delete the bootstrap node. |
|||
|
|||
```sh |
|||
echo 'bootstrap_nodes = 0' >> terraform.tfvars |
|||
terraform apply |
|||
``` |
|||
|
|||
Approve the pending CSRs. |
|||
|
|||
```sh |
|||
for i in {0..120}; do |
|||
ssh -A "$bastion" oc --kubeconfig="$cluster/auth/kubeconfig" get csr --no-headers \ |
|||
| awk '/Pending/ {print $1}' \ |
|||
| xargs --no-run-if-empty ssh -A "$bastion" oc --kubeconfig="$cluster/auth/kubeconfig" adm certificate approve |
|||
sleep 15 |
|||
done & |
|||
``` |
|||
|
|||
Make sure all CSRs have been issued. |
|||
|
|||
```sh |
|||
ssh -A "$bastion" oc --kubeconfig="$cluster/auth/kubeconfig" get csr --no-headers |
|||
``` |
|||
|
|||
Provision storage for the registry. |
|||
|
|||
```sh |
|||
ssh -A "$bastion" oc apply --kubeconfig="$cluster/auth/kubeconfig" -f - < "$cluster/registry-pv.yaml" |
|||
``` |
|||
|
|||
Patch the registry to use the new storage. |
|||
|
|||
```sh |
|||
ssh -A "$bastion" oc patch --kubeconfig="$cluster/auth/kubeconfig" configs.imageregistry.operator.openshift.io cluster --type='json' --patch-file=/dev/fd/0 <<EOF |
|||
[{"op": "remove", "path": "/spec/storage" },{"op": "add", "path": "/spec/storage", "value": {"pvc":{"claim": "registry-storage"}}}] |
|||
EOF |
|||
``` |
|||
|
|||
Deploy the NFS provisioner. |
|||
|
|||
```sh |
|||
ssh -A "$bastion" oc apply --kubeconfig="$cluster/auth/kubeconfig" -f - < "$cluster/nfs-provisioner.yaml" |
|||
``` |
|||
|
|||
Set image registry managementState from Removed to Managed. |
|||
|
|||
```sh |
|||
ssh -A "$bastion" oc patch --kubeconfig="$cluster/auth/kubeconfig" configs.imageregistry.operator.openshift.io cluster --type merge --patch-file=/dev/fd/0 <<EOF |
|||
{"spec":{"managementState": "Managed"}} |
|||
EOF |
|||
``` |
|||
|
|||
Wait for installation to finish. |
|||
|
|||
```sh |
|||
ssh -A "$bastion" openshift-install --dir="$cluster" wait-for install-complete |
|||
``` |
|||
|
|||
## Let's encrypt certificates |
|||
|
|||
Install lego. |
|||
|
|||
```sh |
|||
curl -Lo /tmp/lego.tgz https://github.com/go-acme/lego/releases/download/v4.3.1/lego_v4.3.1_linux_amd64.tar.gz |
|||
sudo tar zxvf /tmp/lego.tgz -C /usr/local/bin lego |
|||
``` |
|||
|
|||
Request a public certificate. |
|||
|
|||
```sh |
|||
export GANDIV5_API_KEY="123...456" |
|||
. "$cluster/dns.env" |
|||
lego -m "nmasse@redhat.com" -d "$LE_API_HOSTNAME" -d "$LE_ROUTER_HOSTNAME" -a --dns gandi run --no-bundle |
|||
``` |
|||
|
|||
Create a secret containing the new router certificate. |
|||
|
|||
```sh |
|||
oc create secret tls router-certs-$(date "+%Y-%m-%d") --cert=$HOME/.lego/certificates/$LE_API_HOSTNAME.crt --key=$HOME/.lego/certificates/$LE_API_HOSTNAME.key -n openshift-ingress --dry-run -o yaml > router.yaml |
|||
ssh -A "$bastion" oc apply -f - -n openshift-ingress < router.yaml |
|||
``` |
|||
|
|||
Update the ingress configuration. |
|||
|
|||
```sh |
|||
ssh -A "$bastion" oc patch ingresscontroller default -n openshift-ingress-operator --type=merge --patch-file=/dev/fd/0 <<EOF |
|||
{"spec": { "defaultCertificate": { "name": "$(date "+%Y-%m-%d")" }}} |
|||
EOF |
|||
``` |
|||
|
|||
Create a secret containing the new certificate. |
|||
|
|||
```sh |
|||
oc create secret tls api-certs-$(date "+%Y-%m-%d") --cert=$HOME/.lego/certificates/$LE_API_HOSTNAME.crt --key=$HOME/.lego/certificates/$LE_API_HOSTNAME.key -n openshift-config --dry-run -o yaml > api.yaml |
|||
ssh -A "$bastion" oc apply -f - -n openshift-config < api.yaml |
|||
``` |
|||
|
|||
Update the apiserver configuration. |
|||
|
|||
```sh |
|||
oc patch apiserver cluster --type=merge --patch-file=/dev/fd/0 <<EOF |
|||
{"spec":{"servingCerts":{"namedCertificates":[{"names":["'$LE_API'"],"servingCertificate":{"name": "api-certs-$(date "+%Y-%m-%d")"}}]}}} |
|||
EOF |
|||
@ -0,0 +1,42 @@ |
|||
resource "libvirt_volume" "bootstrap_disk" { |
|||
name = "${local.bootstrap_name}.${var.volume_format}" |
|||
count = var.bootstrap_nodes |
|||
format = var.volume_format |
|||
pool = var.pool_name |
|||
base_volume_name = "${var.coreos_image}.${var.volume_format}" |
|||
size = var.bootstrap_disk_size |
|||
} |
|||
|
|||
resource "libvirt_ignition" "bootstrap_ignition" { |
|||
name = "${var.cluster_name}-bootstrap-ignition" |
|||
content = file("${path.module}/${var.cluster_name}/bootstrap.ign") |
|||
} |
|||
|
|||
resource "libvirt_domain" "bootstrap" { |
|||
name = local.bootstrap_name |
|||
count = var.bootstrap_nodes |
|||
vcpu = var.bootstrap_vcpu |
|||
memory = var.bootstrap_memory_size |
|||
coreos_ignition = libvirt_ignition.bootstrap_ignition.id |
|||
|
|||
disk { |
|||
volume_id = element(libvirt_volume.bootstrap_disk.*.id, count.index) |
|||
} |
|||
|
|||
# Makes the tty0 available via `virsh console` |
|||
console { |
|||
type = "pty" |
|||
target_port = "0" |
|||
} |
|||
|
|||
network_interface { |
|||
network_id = libvirt_network.ocp_net.id |
|||
addresses = [cidrhost(var.network_ip_range, 5)] |
|||
hostname = "bootstrap" |
|||
|
|||
# When creating the domain resource, wait until the network interface gets |
|||
# a DHCP lease from libvirt, so that the computed IP addresses will be |
|||
# available when the domain is up and the plan applied. |
|||
wait_for_lease = true |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
apiVersion: v1 |
|||
baseDomain: itix.xyz |
|||
compute: |
|||
- name: worker |
|||
hyperthreading: Enabled |
|||
replicas: 3 |
|||
controlPlane: |
|||
name: master |
|||
hyperthreading: Enabled |
|||
replicas: 3 |
|||
metadata: |
|||
name: ocp4 |
|||
networking: |
|||
clusterNetworks: |
|||
- cidr: 10.128.0.0/14 |
|||
hostPrefix: 23 |
|||
serviceNetwork: |
|||
- 172.30.0.0/16 |
|||
networkType: OpenShiftSDN |
|||
platform: |
|||
none: {} |
|||
pullSecret: YOUR_PULL_SECRET_HERE |
|||
sshKey: | |
|||
YOUR_SSH_PUBLIC_KEY_HERE |
|||
@ -0,0 +1,65 @@ |
|||
resource "libvirt_cloudinit_disk" "lb_cloudinit" { |
|||
name = "${local.lb_name}-cloudinit.iso" |
|||
user_data = data.template_file.lb_user_data.rendered |
|||
network_config = data.template_file.lb_network_config.rendered |
|||
pool = var.pool_name |
|||
} |
|||
|
|||
data "template_file" "lb_user_data" { |
|||
template = file("${path.module}/templates/lb/cloud-init.cfg") |
|||
vars = { |
|||
haproxy_cfg = templatefile("${path.module}/templates/lb/haproxy.cfg", { |
|||
master_nodes = { for i in libvirt_domain.master : i.name => i.network_interface.0.addresses[0] }, |
|||
worker_nodes = { for i in libvirt_domain.worker : i.name => i.network_interface.0.addresses[0] }, |
|||
bootstrap_nodes = { for i in libvirt_domain.bootstrap : i.name => i.network_interface.0.addresses[0] } |
|||
}) |
|||
} |
|||
} |
|||
|
|||
data "template_file" "lb_network_config" { |
|||
template = file("${path.module}/templates/lb/network-config.cfg") |
|||
vars = { |
|||
ip = cidrhost(var.network_ip_range, 4) |
|||
dns = cidrhost(var.network_ip_range, 1) |
|||
gw = cidrhost(var.network_ip_range, 1) |
|||
} |
|||
} |
|||
|
|||
resource "libvirt_volume" "lb_disk" { |
|||
name = "${local.lb_name}.${var.volume_format}" |
|||
format = var.volume_format |
|||
pool = var.pool_name |
|||
base_volume_name = "${var.centos_image}.${var.volume_format}" |
|||
size = var.lb_disk_size |
|||
} |
|||
|
|||
resource "libvirt_domain" "lb" { |
|||
name = local.lb_name |
|||
vcpu = var.lb_vcpu |
|||
memory = var.lb_memory_size |
|||
cloudinit = libvirt_cloudinit_disk.lb_cloudinit.id |
|||
autostart = true |
|||
|
|||
disk { |
|||
volume_id = libvirt_volume.lb_disk.id |
|||
} |
|||
|
|||
# Makes the tty0 available via `virsh console` |
|||
console { |
|||
type = "pty" |
|||
target_port = "0" |
|||
} |
|||
|
|||
network_interface { |
|||
network_id = libvirt_network.ocp_net.id |
|||
addresses = [cidrhost(var.network_ip_range, 4)] |
|||
hostname = "lb" |
|||
wait_for_lease = false |
|||
} |
|||
|
|||
network_interface { |
|||
bridge = var.external_ifname |
|||
mac = var.external_mac_address |
|||
wait_for_lease = false |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
terraform { |
|||
required_version = ">= 0.13" |
|||
required_providers { |
|||
libvirt = { |
|||
source = "dmacvicar/libvirt" |
|||
version = ">=0.6.3" |
|||
} |
|||
local = { |
|||
source = "hashicorp/local" |
|||
version = ">=2.0.0" |
|||
} |
|||
template = { |
|||
source = "hashicorp/template" |
|||
version = ">=2.2.0" |
|||
} |
|||
ignition = { |
|||
source = "community-terraform-providers/ignition" |
|||
version = "2.1.2" |
|||
} |
|||
gandi = { |
|||
version = "2.0.0" |
|||
source = "github/go-gandi/gandi" |
|||
} |
|||
} |
|||
} |
|||
|
|||
locals { |
|||
ocp_nodes = { for i in concat(libvirt_domain.bootstrap, libvirt_domain.master, libvirt_domain.worker) : i.name => i.network_interface.0.addresses[0] } |
|||
additional_nodes = { (libvirt_domain.lb.name) = cidrhost(var.network_ip_range, 4), (libvirt_domain.storage.name) = libvirt_domain.storage.network_interface.0.addresses[0] } |
|||
all_nodes = merge(local.ocp_nodes, local.additional_nodes) |
|||
} |
|||
|
|||
output "machines" { |
|||
value = local.all_nodes |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
resource "libvirt_volume" "master_disk" { |
|||
name = "${format(local.master_format, count.index + 1)}.${var.volume_format}" |
|||
count = var.master_nodes |
|||
format = var.volume_format |
|||
pool = var.pool_name |
|||
base_volume_name = "${var.coreos_image}.${var.volume_format}" |
|||
size = var.master_disk_size |
|||
} |
|||
|
|||
resource "libvirt_ignition" "master_ignition" { |
|||
name = "${var.cluster_name}-master-ignition" |
|||
content = file("${path.module}/${var.cluster_name}/master.ign") |
|||
} |
|||
|
|||
resource "libvirt_domain" "master" { |
|||
count = var.master_nodes |
|||
name = format(local.master_format, count.index + 1) |
|||
vcpu = var.master_vcpu |
|||
memory = var.master_memory_size |
|||
coreos_ignition = libvirt_ignition.master_ignition.id |
|||
autostart = true |
|||
|
|||
disk { |
|||
volume_id = element(libvirt_volume.master_disk.*.id, count.index) |
|||
} |
|||
|
|||
# Makes the tty0 available via `virsh console` |
|||
console { |
|||
type = "pty" |
|||
target_port = "0" |
|||
} |
|||
|
|||
network_interface { |
|||
network_id = libvirt_network.ocp_net.id |
|||
addresses = [cidrhost(var.network_ip_range, 11 + count.index)] |
|||
hostname = format("master%d", count.index + 1) |
|||
|
|||
# When creating the domain resource, wait until the network interface gets |
|||
# a DHCP lease from libvirt, so that the computed IP addresses will be |
|||
# available when the domain is up and the plan applied. |
|||
wait_for_lease = true |
|||
} |
|||
} |
|||
@ -0,0 +1,36 @@ |
|||
resource "libvirt_network" "ocp_net" { |
|||
name = var.cluster_name |
|||
mode = "nat" |
|||
domain = local.network_domain |
|||
addresses = [var.network_ip_range] |
|||
autostart = true |
|||
|
|||
dns { |
|||
enabled = true |
|||
|
|||
hosts { |
|||
hostname = "host" |
|||
ip = cidrhost(var.network_ip_range, 1) |
|||
} |
|||
hosts { |
|||
hostname = "api" |
|||
ip = cidrhost(var.network_ip_range, 4) |
|||
} |
|||
hosts { |
|||
hostname = "api-int" |
|||
ip = cidrhost(var.network_ip_range, 4) |
|||
} |
|||
hosts { |
|||
hostname = "etcd" |
|||
ip = cidrhost(var.network_ip_range, 4) |
|||
} |
|||
} |
|||
|
|||
dhcp { |
|||
enabled = true |
|||
} |
|||
|
|||
xml { |
|||
xslt = templatefile("${path.module}/templates/network.xslt", { alias = "apps.${local.network_domain}", ip = cidrhost(var.network_ip_range, 4) }) |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
resource "local_file" "registry_pv" { |
|||
content = templatefile("${path.module}/templates/registry-pv.yaml", { nfs_server = libvirt_domain.storage.network_interface.0.addresses[0] }) |
|||
filename = "${var.cluster_name}/registry-pv.yaml" |
|||
file_permission = "0644" |
|||
} |
|||
|
|||
resource "local_file" "nfs_provisioner" { |
|||
content = templatefile("${path.module}/templates/nfs-provisioner.yaml", { nfs_server = libvirt_domain.storage.network_interface.0.addresses[0] }) |
|||
filename = "${var.cluster_name}/nfs-provisioner.yaml" |
|||
file_permission = "0644" |
|||
} |
|||
|
|||
resource "local_file" "dns_config" { |
|||
content = templatefile("${path.module}/templates/dns.env", { api_server = "api.${local.network_domain}", router = "*.apps.${local.network_domain}", dns_zone = var.base_domain, cluster_name = var.cluster_name }) |
|||
filename = "${var.cluster_name}/dns.env" |
|||
file_permission = "0644" |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
provider "libvirt" { |
|||
uri = "qemu:///system" |
|||
} |
|||
|
|||
provider "gandi" { |
|||
# key = "<livedns apikey>" |
|||
# sharing_id = "<sharing id>" |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
data "gandi_domain" "public_domain" { |
|||
name = var.base_domain |
|||
} |
|||
|
|||
resource "gandi_livedns_record" "api_record" { |
|||
zone = data.gandi_domain.public_domain.id |
|||
name = "api.ocp4" |
|||
type = "A" |
|||
ttl = 300 |
|||
values = [ |
|||
var.public_cluster_ip |
|||
] |
|||
} |
|||
|
|||
resource "gandi_livedns_record" "router_record" { |
|||
zone = data.gandi_domain.public_domain.id |
|||
name = "*.apps.ocp4" |
|||
type = "A" |
|||
ttl = 300 |
|||
values = [ |
|||
var.public_cluster_ip |
|||
] |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
resource "libvirt_cloudinit_disk" "storage_cloudinit" { |
|||
name = "${local.storage_name}-cloudinit.iso" |
|||
user_data = data.template_file.storage_user_data.rendered |
|||
network_config = data.template_file.storage_network_config.rendered |
|||
pool = var.pool_name |
|||
} |
|||
|
|||
data "template_file" "storage_user_data" { |
|||
template = file("${path.module}/templates/storage/cloud-init.cfg") |
|||
} |
|||
|
|||
data "template_file" "storage_network_config" { |
|||
template = file("${path.module}/templates/storage/network-config.cfg") |
|||
} |
|||
|
|||
resource "libvirt_volume" "storage_os_disk" { |
|||
name = "${local.storage_name}-os.${var.volume_format}" |
|||
format = var.volume_format |
|||
pool = var.pool_name |
|||
base_volume_name = "${var.centos_image}.${var.volume_format}" |
|||
} |
|||
|
|||
resource "libvirt_volume" "storage_data_disk" { |
|||
name = "${local.storage_name}-data.${var.volume_format}" |
|||
format = var.volume_format |
|||
pool = var.pool_name |
|||
size = var.storage_disk_size |
|||
} |
|||
|
|||
resource "libvirt_domain" "storage" { |
|||
name = local.storage_name |
|||
vcpu = var.storage_vcpu |
|||
memory = var.storage_memory_size |
|||
cloudinit = libvirt_cloudinit_disk.storage_cloudinit.id |
|||
autostart = true |
|||
|
|||
disk { |
|||
volume_id = libvirt_volume.storage_os_disk.id |
|||
} |
|||
|
|||
disk { |
|||
volume_id = libvirt_volume.storage_data_disk.id |
|||
} |
|||
|
|||
# Makes the tty0 available via `virsh console` |
|||
console { |
|||
type = "pty" |
|||
target_port = "0" |
|||
} |
|||
|
|||
network_interface { |
|||
network_id = libvirt_network.ocp_net.id |
|||
addresses = [cidrhost(var.network_ip_range, 6)] |
|||
hostname = "storage" |
|||
|
|||
# When creating the domain resource, wait until the network interface gets |
|||
# a DHCP lease from libvirt, so that the computed IP addresses will be |
|||
# available when the domain is up and the plan applied. |
|||
wait_for_lease = true |
|||
} |
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
export LE_API_HOSTNAME="${api_server}" |
|||
export LE_ROUTER_HOSTNAME="${router}" |
|||
export DNS_ZONE="${dns_zone}" |
|||
export DNS_API_RECORD="api.${cluster_name}" |
|||
export DNS_ROUTER_RECORD="*.apps.${cluster_name}" |
|||
@ -0,0 +1,85 @@ |
|||
#cloud-config |
|||
# vim: syntax=yaml |
|||
|
|||
resize_rootfs: true |
|||
|
|||
users: |
|||
- name: nicolas |
|||
gecos: Nicolas MASSE |
|||
groups: wheel |
|||
lock_passwd: false |
|||
passwd: $6$XUTB20jVVXIqh78k$L1A9Lft5JlbOtNbeDP.fOZ5giLl09LfJGGCon5uwtsIhPJoNkj4SIk08Rb6vSowOps2ik5tlUwT2ZOZ6jjr7.0 |
|||
ssh_authorized_keys: |
|||
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPR1tt58X0+vbvsCR12gMAqr+g7vjt1Fx/qqz9EiboIs nicolas@localhost.localdomain |
|||
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFW62WJXI1ZCMfNA4w0dMpL0fsldhbEfULNGIUB0nQui nmasse@localhost.localdomain |
|||
|
|||
packages: |
|||
# Useful tools |
|||
- net-tools |
|||
- hdparm |
|||
- iptraf |
|||
- iotop |
|||
- vim-enhanced |
|||
- tmux |
|||
- rsync |
|||
- tree |
|||
- unzip |
|||
- tar |
|||
- tcpdump |
|||
- telnet |
|||
- strace |
|||
- bind-utils |
|||
# Load Balancer |
|||
- haproxy |
|||
- firewalld |
|||
|
|||
runcmd: |
|||
# Enable KVM virsh console access |
|||
- [ "systemctl", "enable", "serial-getty@ttyS0.service" ] |
|||
- [ "systemctl", "start", "--no-block", "serial-getty@ttyS0.service" ] |
|||
# Disable SSH password authentication |
|||
- [ "sed", "-i.post-install", "-e", "s/PasswordAuthentication yes/PasswordAuthentication no/", "/etc/ssh/sshd_config" ] |
|||
- [ "systemctl", "restart", "sshd" ] |
|||
# Enable sudo without password |
|||
- [ "sed", "-i.post-install", "-e", "s/^%wheel\tALL=(ALL)\tALL/%wheel ALL=(ALL) NOPASSWD: ALL/", "/etc/sudoers" ] |
|||
# Fix file permissions |
|||
- [ "chown", "-R", "nicolas:nicolas", "/home/nicolas" ] |
|||
# Configure HAProxy |
|||
- [ "systemctl", "enable", "firewalld" ] |
|||
- [ "systemctl", "start", "firewalld" ] |
|||
- [ "setsebool", "-P", "haproxy_connect_any=1" ] |
|||
- [ "systemctl", "enable", "haproxy" ] |
|||
- [ "systemctl", "restart", "haproxy" ] |
|||
- [ "firewall-cmd", "--add-service=http", "--permanent" ] |
|||
- [ "firewall-cmd", "--add-service=https", "--permanent" ] |
|||
- [ "firewall-cmd", "--add-port=6443/tcp", "--permanent" ] |
|||
- [ "firewall-cmd", "--add-port=22623/tcp", "--permanent" ] |
|||
- [ "firewall-cmd", "--reload" ] |
|||
|
|||
write_files: |
|||
- path: /root/.bashrc |
|||
# PS1='\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]# ' |
|||
content: | |
|||
UFMxPSdcW1wwMzNbMDE7MzFtXF1cdUBcaFxbXDAzM1swMG1cXTpcW1wwMzNbMDE7MzRtXF1cd1xb |
|||
XDAzM1swMG1cXSMgJwo= |
|||
encoding: base64 |
|||
append: true |
|||
|
|||
- path: /etc/skel/.bashrc |
|||
# PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' |
|||
content: | |
|||
UFMxPSdcW1wwMzNbMDE7MzJtXF1cdUBcaFxbXDAzM1swMG1cXTpcW1wwMzNbMDE7MzRtXF1cd1xb |
|||
XDAzM1swMG1cXVwkICcK |
|||
encoding: base64 |
|||
append: true |
|||
|
|||
- path: /home/nicolas/.bashrc |
|||
# PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' |
|||
content: | |
|||
UFMxPSdcW1wwMzNbMDE7MzJtXF1cdUBcaFxbXDAzM1swMG1cXTpcW1wwMzNbMDE7MzRtXF1cd1xb |
|||
XDAzM1swMG1cXVwkICcK |
|||
encoding: base64 |
|||
append: true |
|||
|
|||
- path: /etc/haproxy/haproxy.cfg |
|||
content: ${jsonencode(haproxy_cfg)} |
|||
@ -0,0 +1,74 @@ |
|||
global |
|||
log 127.0.0.1 local2 |
|||
|
|||
chroot /var/lib/haproxy |
|||
pidfile /var/run/haproxy.pid |
|||
maxconn 4000 |
|||
user haproxy |
|||
group haproxy |
|||
|
|||
# turn on stats unix socket |
|||
stats socket /var/lib/haproxy/stats |
|||
|
|||
|
|||
|
|||
|
|||
#--------------------------------------------------------------------- |
|||
# common defaults that all the 'listen' and 'backend' sections will |
|||
# use if not designated in their block |
|||
#--------------------------------------------------------------------- |
|||
|
|||
defaults |
|||
mode http |
|||
log global |
|||
option dontlognull |
|||
option redispatch |
|||
retries 3 |
|||
timeout http-request 10s |
|||
timeout queue 1m |
|||
timeout connect 10s |
|||
timeout client 1m |
|||
timeout server 1m |
|||
timeout http-keep-alive 10s |
|||
timeout check 10s |
|||
maxconn 3000 |
|||
|
|||
listen ingress-http |
|||
bind 0.0.0.0:80 |
|||
mode tcp |
|||
%{for name, ip in master_nodes~} |
|||
server ${name} ${ip}:80 check |
|||
%{endfor~} |
|||
%{for name, ip in worker_nodes~} |
|||
server ${name} ${ip}:80 check |
|||
%{endfor~} |
|||
|
|||
listen ingress-https |
|||
bind 0.0.0.0:443 |
|||
mode tcp |
|||
%{for name, ip in master_nodes~} |
|||
server ${name} ${ip}:443 check |
|||
%{endfor~} |
|||
%{for name, ip in worker_nodes~} |
|||
server ${name} ${ip}:443 check |
|||
%{endfor~} |
|||
|
|||
listen api |
|||
bind 0.0.0.0:6443 |
|||
mode tcp |
|||
%{for name, ip in master_nodes~} |
|||
server ${name} ${ip}:6443 check |
|||
%{endfor~} |
|||
%{for name, ip in bootstrap_nodes~} |
|||
server ${name} ${ip}:6443 check |
|||
%{endfor~} |
|||
|
|||
listen machine-config-server |
|||
bind 0.0.0.0:22623 |
|||
mode tcp |
|||
%{for name, ip in master_nodes~} |
|||
server ${name} ${ip}:22623 check |
|||
%{endfor~} |
|||
%{for name, ip in bootstrap_nodes~} |
|||
server ${name} ${ip}:22623 check |
|||
%{endfor~} |
|||
@ -0,0 +1,11 @@ |
|||
version: 2 |
|||
ethernets: |
|||
eth0: |
|||
addresses: |
|||
- ${ip}/24 |
|||
#gateway4: ${gw} |
|||
nameservers: |
|||
addresses: [${dns}] |
|||
eth1: |
|||
dhcp4: true |
|||
nameservers: {} |
|||
@ -0,0 +1,25 @@ |
|||
<?xml version="1.0" ?> |
|||
<xsl:stylesheet version="1.0" |
|||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" |
|||
xmlns:dnsmasq="http://libvirt.org/schemas/network/dnsmasq/1.0"> |
|||
<xsl:output omit-xml-declaration="yes" indent="yes"/> |
|||
|
|||
<!-- Identity transform --> |
|||
<xsl:template match="node()|@*"> |
|||
<xsl:copy> |
|||
<xsl:apply-templates select="node()|@*"/> |
|||
</xsl:copy> |
|||
</xsl:template> |
|||
|
|||
<!-- Append custom dnsmasq options to the network element --> |
|||
<xsl:template match="/network"> |
|||
<xsl:copy> |
|||
<xsl:copy-of select="@*"/> |
|||
<xsl:copy-of select="node()"/> |
|||
<dnsmasq:options> |
|||
<dnsmasq:option value="address=/${alias}/${ip}"/> |
|||
</dnsmasq:options> |
|||
</xsl:copy> |
|||
</xsl:template> |
|||
|
|||
</xsl:stylesheet> |
|||
@ -0,0 +1,115 @@ |
|||
kind: Namespace |
|||
apiVersion: v1 |
|||
metadata: |
|||
name: "openshift-nfs-provisioner" |
|||
--- |
|||
kind: ServiceAccount |
|||
apiVersion: v1 |
|||
metadata: |
|||
name: nfs-client-provisioner |
|||
namespace: "openshift-nfs-provisioner" |
|||
--- |
|||
kind: ClusterRole |
|||
apiVersion: rbac.authorization.k8s.io/v1 |
|||
metadata: |
|||
name: nfs-client-provisioner-runner |
|||
rules: |
|||
- apiGroups: [""] |
|||
resources: ["persistentvolumes"] |
|||
verbs: ["get", "list", "watch", "create", "delete"] |
|||
- apiGroups: [""] |
|||
resources: ["persistentvolumeclaims"] |
|||
verbs: ["get", "list", "watch", "update"] |
|||
- apiGroups: ["storage.k8s.io"] |
|||
resources: ["storageclasses"] |
|||
verbs: ["get", "list", "watch"] |
|||
- apiGroups: [""] |
|||
resources: ["events"] |
|||
verbs: ["create", "update", "patch"] |
|||
--- |
|||
kind: ClusterRoleBinding |
|||
apiVersion: rbac.authorization.k8s.io/v1 |
|||
metadata: |
|||
name: run-nfs-client-provisioner |
|||
subjects: |
|||
- kind: ServiceAccount |
|||
name: nfs-client-provisioner |
|||
namespace: "openshift-nfs-provisioner" |
|||
roleRef: |
|||
kind: ClusterRole |
|||
name: nfs-client-provisioner-runner |
|||
apiGroup: rbac.authorization.k8s.io |
|||
--- |
|||
kind: Role |
|||
apiVersion: rbac.authorization.k8s.io/v1 |
|||
metadata: |
|||
name: nfs-client-provisioner |
|||
namespace: "openshift-nfs-provisioner" |
|||
rules: |
|||
- apiGroups: [""] |
|||
resources: ["endpoints"] |
|||
verbs: ["get", "list", "watch", "create", "update", "patch"] |
|||
- apiGroups: ["security.openshift.io"] |
|||
resourceNames: ["hostmount-anyuid"] |
|||
resources: ["securitycontextconstraints"] |
|||
verbs: ["use"] |
|||
--- |
|||
kind: RoleBinding |
|||
apiVersion: rbac.authorization.k8s.io/v1 |
|||
metadata: |
|||
name: nfs-client-provisioner |
|||
namespace: "openshift-nfs-provisioner" |
|||
subjects: |
|||
- kind: ServiceAccount |
|||
name: nfs-client-provisioner |
|||
roleRef: |
|||
kind: Role |
|||
name: nfs-client-provisioner |
|||
apiGroup: rbac.authorization.k8s.io |
|||
--- |
|||
kind: Deployment |
|||
apiVersion: apps/v1 |
|||
metadata: |
|||
name: nfs-client-provisioner |
|||
namespace: "openshift-nfs-provisioner" |
|||
spec: |
|||
replicas: 1 |
|||
selector: |
|||
matchLabels: |
|||
app: nfs-client-provisioner |
|||
strategy: |
|||
type: Recreate |
|||
template: |
|||
metadata: |
|||
labels: |
|||
app: nfs-client-provisioner |
|||
spec: |
|||
serviceAccountName: nfs-client-provisioner |
|||
containers: |
|||
- name: nfs-client-provisioner |
|||
image: quay.io/external_storage/nfs-client-provisioner:latest |
|||
volumeMounts: |
|||
- name: nfs-client-root |
|||
mountPath: /persistentvolumes |
|||
env: |
|||
- name: PROVISIONER_NAME |
|||
value: redhat-emea-ssa-team/hetzner-ocp4 |
|||
- name: NFS_SERVER |
|||
value: "${nfs_server}" |
|||
- name: NFS_PATH |
|||
value: "/srv/nfs/pv-user-pvs" |
|||
volumes: |
|||
- name: nfs-client-root |
|||
nfs: |
|||
server: "${nfs_server}" |
|||
path: "/srv/nfs/pv-user-pvs" |
|||
--- |
|||
apiVersion: storage.k8s.io/v1 |
|||
kind: StorageClass |
|||
metadata: |
|||
name: managed-nfs-storage |
|||
annotations: |
|||
storageclass.kubernetes.io/is-default-class: "true" |
|||
provisioner: redhat-emea-ssa-team/hetzner-ocp4 |
|||
parameters: |
|||
archiveOnDelete: "false" |
|||
@ -0,0 +1,25 @@ |
|||
apiVersion: v1 |
|||
kind: PersistentVolume |
|||
metadata: |
|||
name: nfs-registry-storage |
|||
spec: |
|||
accessModes: |
|||
- ReadWriteMany |
|||
capacity: |
|||
storage: 100Gi |
|||
nfs: |
|||
path: "/srv/nfs/pv-infra-registry" |
|||
server: "${nfs_server}" |
|||
persistentVolumeReclaimPolicy: Recycle |
|||
--- |
|||
apiVersion: v1 |
|||
kind: PersistentVolumeClaim |
|||
metadata: |
|||
name: registry-storage |
|||
namespace: openshift-image-registry |
|||
spec: |
|||
accessModes: |
|||
- ReadWriteMany |
|||
resources: |
|||
requests: |
|||
storage: 100Gi |
|||
@ -0,0 +1,104 @@ |
|||
#cloud-config |
|||
# vim: syntax=yaml |
|||
|
|||
disk_setup: |
|||
/dev/vdb: |
|||
table_type: mbr |
|||
layout: |
|||
- 100 |
|||
overwrite: false |
|||
fs_setup: |
|||
- label: storage |
|||
filesystem: xfs |
|||
device: /dev/vdb |
|||
partition: 1 |
|||
resize_rootfs: true |
|||
|
|||
mounts: |
|||
- [ "/dev/vdb1", "/srv", "xfs", "defaults", "0", "0" ] |
|||
|
|||
users: |
|||
- name: nicolas |
|||
gecos: Nicolas MASSE |
|||
groups: wheel |
|||
lock_passwd: false |
|||
passwd: $6$XUTB20jVVXIqh78k$L1A9Lft5JlbOtNbeDP.fOZ5giLl09LfJGGCon5uwtsIhPJoNkj4SIk08Rb6vSowOps2ik5tlUwT2ZOZ6jjr7.0 |
|||
ssh_authorized_keys: |
|||
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPR1tt58X0+vbvsCR12gMAqr+g7vjt1Fx/qqz9EiboIs nicolas@localhost.localdomain |
|||
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFW62WJXI1ZCMfNA4w0dMpL0fsldhbEfULNGIUB0nQui nmasse@localhost.localdomain |
|||
|
|||
packages: |
|||
# Useful tools |
|||
- net-tools |
|||
- hdparm |
|||
- iptraf |
|||
- iotop |
|||
- vim-enhanced |
|||
- tmux |
|||
- rsync |
|||
- tree |
|||
- unzip |
|||
- tar |
|||
- tcpdump |
|||
- telnet |
|||
- strace |
|||
- bind-utils |
|||
# NFS |
|||
- firewalld |
|||
- nfs-utils |
|||
|
|||
runcmd: |
|||
# Enable KVM virsh console access |
|||
- [ "systemctl", "enable", "serial-getty@ttyS0.service" ] |
|||
- [ "systemctl", "start", "--no-block", "serial-getty@ttyS0.service" ] |
|||
# Disable SSH password authentication |
|||
- [ "sed", "-i.post-install", "-e", "s/PasswordAuthentication yes/PasswordAuthentication no/", "/etc/ssh/sshd_config" ] |
|||
- [ "systemctl", "restart", "sshd" ] |
|||
# Enable sudo without password |
|||
- [ "sed", "-i.post-install", "-e", "s/^%wheel\tALL=(ALL)\tALL/%wheel ALL=(ALL) NOPASSWD: ALL/", "/etc/sudoers" ] |
|||
# Fix file permissions |
|||
- [ "chown", "-R", "nicolas:nicolas", "/home/nicolas" ] |
|||
# Enable NFS |
|||
- [ "mount", "/srv" ] |
|||
- [ "systemctl", "enable", "rpcbind" ] |
|||
- [ "systemctl", "start", "rpcbind" ] |
|||
- [ "systemctl", "enable", "nfs-server" ] |
|||
- [ "systemctl", "start", "nfs-server" ] |
|||
- [ "systemctl", "enable", "firewalld" ] |
|||
- [ "systemctl", "start", "firewalld" ] |
|||
- [ "setsebool", "-P", "nfs_export_all_rw", "1" ] |
|||
- [ "mkdir", "-p", "/srv/nfs" ] |
|||
- [ "exportfs", "-rav" ] |
|||
#- [ "/bin/bash", "-c", "for i in {0..999}; do pv=$(printf '/srv/nfs/pv-%03d\n' $i); mkdir $pv; chmod 777 $pv; done" ] |
|||
- [ "/bin/bash", "-c", "for pv in pv-infra-registry pv-user-pvs; do mkdir -p /srv/nfs/$pv; chmod 770 /srv/nfs/$pv; done" ] |
|||
- [ "firewall-cmd", "--add-service=nfs", "--permanent" ] |
|||
- [ "firewall-cmd", "--reload" ] |
|||
|
|||
write_files: |
|||
- path: /root/.bashrc |
|||
# PS1='\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]# ' |
|||
content: | |
|||
UFMxPSdcW1wwMzNbMDE7MzFtXF1cdUBcaFxbXDAzM1swMG1cXTpcW1wwMzNbMDE7MzRtXF1cd1xb |
|||
XDAzM1swMG1cXSMgJwo= |
|||
encoding: base64 |
|||
append: true |
|||
|
|||
- path: /etc/skel/.bashrc |
|||
# PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' |
|||
content: | |
|||
UFMxPSdcW1wwMzNbMDE7MzJtXF1cdUBcaFxbXDAzM1swMG1cXTpcW1wwMzNbMDE7MzRtXF1cd1xb |
|||
XDAzM1swMG1cXVwkICcK |
|||
encoding: base64 |
|||
append: true |
|||
|
|||
- path: /home/nicolas/.bashrc |
|||
# PS1='\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' |
|||
content: | |
|||
UFMxPSdcW1wwMzNbMDE7MzJtXF1cdUBcaFxbXDAzM1swMG1cXTpcW1wwMzNbMDE7MzRtXF1cd1xb |
|||
XDAzM1swMG1cXVwkICcK |
|||
encoding: base64 |
|||
append: true |
|||
|
|||
- path: /etc/exports |
|||
content: | |
|||
/srv/nfs *(rw,no_root_squash) |
|||
@ -0,0 +1,4 @@ |
|||
version: 2 |
|||
ethernets: |
|||
eth0: |
|||
dhcp4: true |
|||
@ -0,0 +1,146 @@ |
|||
variable "master_nodes" { |
|||
type = number |
|||
default = 3 |
|||
} |
|||
|
|||
variable "worker_nodes" { |
|||
type = number |
|||
default = 3 |
|||
} |
|||
|
|||
variable "bootstrap_nodes" { |
|||
type = number |
|||
default = 1 |
|||
} |
|||
|
|||
variable "pool_name" { |
|||
type = string |
|||
default = "default" |
|||
} |
|||
|
|||
variable "volume_format" { |
|||
type = string |
|||
default = "qcow2" |
|||
} |
|||
|
|||
variable "centos_image" { |
|||
type = string |
|||
default = "centos-stream-8" |
|||
} |
|||
|
|||
variable "coreos_image" { |
|||
type = string |
|||
default = "rhcos-4.7.0-x86_64-qemu.x86_64" |
|||
} |
|||
|
|||
variable "cluster_name" { |
|||
type = string |
|||
default = "ocp4" |
|||
} |
|||
|
|||
variable "external_ifname" { |
|||
type = string |
|||
default = "virbr1" |
|||
} |
|||
|
|||
variable "external_mac_address" { |
|||
type = string |
|||
} |
|||
|
|||
variable "base_domain" { |
|||
type = string |
|||
default = "ocp.lab" |
|||
} |
|||
|
|||
variable "network_ip_range" { |
|||
type = string |
|||
default = "10.10.3.0/24" |
|||
} |
|||
|
|||
variable "public_cluster_ip" { |
|||
type = string |
|||
} |
|||
|
|||
variable "master_disk_size" { |
|||
type = number |
|||
default = 120 * 1024 * 1024 * 1024 |
|||
} |
|||
|
|||
variable "master_vcpu" { |
|||
type = number |
|||
default = 4 |
|||
} |
|||
|
|||
variable "master_memory_size" { |
|||
type = number |
|||
default = 16 * 1024 |
|||
} |
|||
|
|||
variable "lb_disk_size" { |
|||
type = number |
|||
default = 10 * 1024 * 1024 * 1024 |
|||
} |
|||
|
|||
variable "lb_vcpu" { |
|||
type = number |
|||
default = 2 |
|||
} |
|||
|
|||
variable "lb_memory_size" { |
|||
type = number |
|||
default = 4 * 1024 |
|||
} |
|||
|
|||
variable "storage_disk_size" { |
|||
type = number |
|||
default = 120 * 1024 * 1024 * 1024 |
|||
} |
|||
|
|||
variable "storage_vcpu" { |
|||
type = number |
|||
default = 2 |
|||
} |
|||
|
|||
variable "storage_memory_size" { |
|||
type = number |
|||
default = 8 * 1024 |
|||
} |
|||
|
|||
variable "worker_disk_size" { |
|||
type = number |
|||
default = 120 * 1024 * 1024 * 1024 |
|||
} |
|||
|
|||
variable "worker_vcpu" { |
|||
type = number |
|||
default = 2 |
|||
} |
|||
|
|||
variable "worker_memory_size" { |
|||
type = number |
|||
default = 8 * 1024 |
|||
} |
|||
|
|||
variable "bootstrap_disk_size" { |
|||
type = number |
|||
default = 120 * 1024 * 1024 * 1024 |
|||
} |
|||
|
|||
variable "bootstrap_vcpu" { |
|||
type = number |
|||
default = 4 |
|||
} |
|||
|
|||
variable "bootstrap_memory_size" { |
|||
type = number |
|||
default = 16 * 1024 |
|||
} |
|||
|
|||
locals { |
|||
master_format = "${var.cluster_name}-master-%02d" |
|||
worker_format = "${var.cluster_name}-worker-%02d" |
|||
bootstrap_name = "${var.cluster_name}-bootstrap" |
|||
storage_name = "${var.cluster_name}-storage" |
|||
lb_name = "${var.cluster_name}-lb" |
|||
network_domain = "${var.cluster_name}.${var.base_domain}" |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
resource "libvirt_volume" "worker_disk" { |
|||
name = "${format(local.worker_format, count.index + 1)}.${var.volume_format}" |
|||
count = var.worker_nodes |
|||
format = var.volume_format |
|||
pool = var.pool_name |
|||
base_volume_name = "${var.coreos_image}.${var.volume_format}" |
|||
size = var.worker_disk_size |
|||
} |
|||
|
|||
resource "libvirt_ignition" "worker_ignition" { |
|||
name = "${var.cluster_name}-worker-ignition" |
|||
content = file("${path.module}/${var.cluster_name}/worker.ign") |
|||
} |
|||
|
|||
resource "libvirt_domain" "worker" { |
|||
count = var.worker_nodes |
|||
name = format(local.worker_format, count.index + 1) |
|||
vcpu = var.worker_vcpu |
|||
memory = var.worker_memory_size |
|||
coreos_ignition = libvirt_ignition.worker_ignition.id |
|||
autostart = true |
|||
|
|||
disk { |
|||
volume_id = element(libvirt_volume.worker_disk.*.id, count.index) |
|||
} |
|||
|
|||
# Makes the tty0 available via `virsh console` |
|||
console { |
|||
type = "pty" |
|||
target_port = "0" |
|||
} |
|||
|
|||
network_interface { |
|||
network_id = libvirt_network.ocp_net.id |
|||
addresses = [cidrhost(var.network_ip_range, 21 + count.index)] |
|||
hostname = format("worker%d", count.index + 1) |
|||
|
|||
# When creating the domain resource, wait until the network interface gets |
|||
# a DHCP lease from libvirt, so that the computed IP addresses will be |
|||
# available when the domain is up and the plan applied. |
|||
wait_for_lease = true |
|||
} |
|||
} |
|||
Loading…
Reference in new issue