Re: [PATCH v1 6/6] terraform: Use the alternate ssh port for Ansible control

Chuck Lever <[email protected]> Thu, 2 Oct 2025 16:25:34 -0400
Newsgroups dev.linux.lists.kdevops
Message-ID <[email protected]>
On 10/2/25 4:21 PM, Chuck Lever wrote:
> From: Chuck Lever <[email protected]>
> 
> When provisioning guestfs instances, make use of the Ansible ssh

Ooops. Copy-pasta : should be "When provisioning terraform guests,"


> port setting, in case it is set to something other than port 22.
> 
> Generated-by: Claude AI
> Signed-off-by: Chuck Lever <[email protected]>
> ---
>  .../templates/aws/terraform.tfvars.j2         |  1 +
>  .../templates/azure/terraform.tfvars.j2       |  1 +
>  .../templates/gce/terraform.tfvars.j2         |  1 +
>  .../templates/lambdalabs/terraform.tfvars.j2  |  1 +
>  .../templates/oci/terraform.tfvars.j2         |  1 +
>  .../templates/openstack/terraform.tfvars.j2   |  1 +
>  .../roles/terraform/templates/ssh_config.j2   |  2 +-
>  scripts/update_ssh_config_lambdalabs.py       | 18 ++++++--
>  terraform/aws/main.tf                         |  5 ++-
>  terraform/azure/main.tf                       |  9 +++-
>  terraform/gce/main.tf                         | 23 +++++++++-
>  terraform/lambdalabs/main.tf                  | 43 +++++++++++++++++-
>  terraform/oci/main.tf                         | 11 ++++-
>  terraform/openstack/main.tf                   | 11 ++++-
>  terraform/scripts/cloud-init.sh               | 44 ++++++++++++++++++-
>  terraform/shared.tf                           |  6 +++
>  16 files changed, 162 insertions(+), 16 deletions(-)
> 
> diff --git a/playbooks/roles/gen_tfvars/templates/aws/terraform.tfvars.j2 b/playbooks/roles/gen_tfvars/templates/aws/terraform.tfvars.j2
> index 4b20667f0686..fc9c94441ded 100644
> --- a/playbooks/roles/gen_tfvars/templates/aws/terraform.tfvars.j2
> +++ b/playbooks/roles/gen_tfvars/templates/aws/terraform.tfvars.j2
> @@ -18,6 +18,7 @@ aws_ebs_volume_throughput = {{ terraform_aws_ebs_volume_throughput }}
>  ssh_config_pubkey_file = "{{ kdevops_terraform_ssh_config_pubkey_file }}"
>  ssh_config_user = "{{ kdevops_terraform_ssh_config_user }}"
>  ssh_config = "{{ sshconfig }}"
> +ssh_config_port = {{ ansible_cfg_ssh_port }}
>  
>  ssh_config_update = "{{ kdevops_terraform_ssh_config_update | lower }}"
>  ssh_config_use_strict_settings = "{{ kdevops_terraform_ssh_config_update_strict  | lower }}"
> diff --git a/playbooks/roles/gen_tfvars/templates/azure/terraform.tfvars.j2 b/playbooks/roles/gen_tfvars/templates/azure/terraform.tfvars.j2
> index 7ce0f6170e22..9c3ac0a0f7f6 100644
> --- a/playbooks/roles/gen_tfvars/templates/azure/terraform.tfvars.j2
> +++ b/playbooks/roles/gen_tfvars/templates/azure/terraform.tfvars.j2
> @@ -13,6 +13,7 @@ azure_managed_disks_tier = "{{ terraform_azure_managed_disks_tier }}"
>  ssh_config_pubkey_file = "{{ kdevops_terraform_ssh_config_pubkey_file }}"
>  ssh_config_user = "{{ kdevops_terraform_ssh_config_user }}"
>  ssh_config = "{{ sshconfig }}"
> +ssh_config_port = {{ ansible_cfg_ssh_port }}
>  
>  ssh_config_update = "{{ kdevops_terraform_ssh_config_update | lower }}"
>  ssh_config_use_strict_settings = "{{ kdevops_terraform_ssh_config_update_strict | lower }}"
> diff --git a/playbooks/roles/gen_tfvars/templates/gce/terraform.tfvars.j2 b/playbooks/roles/gen_tfvars/templates/gce/terraform.tfvars.j2
> index c6093aeff634..950e12b786fb 100644
> --- a/playbooks/roles/gen_tfvars/templates/gce/terraform.tfvars.j2
> +++ b/playbooks/roles/gen_tfvars/templates/gce/terraform.tfvars.j2
> @@ -20,6 +20,7 @@ gce_disk_throughput = {{ terraform_gce_disk_throughput }}
>  ssh_config_pubkey_file = "{{ kdevops_terraform_ssh_config_pubkey_file }}"
>  ssh_config_user = "{{ kdevops_terraform_ssh_config_user }}"
>  ssh_config = "{{ sshconfig }}"
> +ssh_config_port = {{ ansible_cfg_ssh_port }}
>  
>  ssh_config_update = "{{ kdevops_terraform_ssh_config_update | lower }}"
>  ssh_config_use_strict_settings = "{{ kdevops_terraform_ssh_config_update_strict | lower }}"
> diff --git a/playbooks/roles/gen_tfvars/templates/lambdalabs/terraform.tfvars.j2 b/playbooks/roles/gen_tfvars/templates/lambdalabs/terraform.tfvars.j2
> index 4fd8cad634aa..a4ba26fc1d7e 100644
> --- a/playbooks/roles/gen_tfvars/templates/lambdalabs/terraform.tfvars.j2
> +++ b/playbooks/roles/gen_tfvars/templates/lambdalabs/terraform.tfvars.j2
> @@ -7,6 +7,7 @@ ssh_config_pubkey_file = "{{ kdevops_terraform_ssh_config_pubkey_file }}"
>  ssh_config_privkey_file = "{{ kdevops_terraform_ssh_config_privkey_file }}"
>  ssh_config_user = "{{ kdevops_terraform_ssh_config_user }}"
>  ssh_config = "{{ sshconfig }}"
> +ssh_config_port = {{ ansible_cfg_ssh_port }}
>  # Use unique SSH config file per directory to avoid conflicts
>  ssh_config_name = "{{ kdevops_ssh_config_prefix }}{{ topdir_path_sha256sum[:8] }}"
>  
> diff --git a/playbooks/roles/gen_tfvars/templates/oci/terraform.tfvars.j2 b/playbooks/roles/gen_tfvars/templates/oci/terraform.tfvars.j2
> index 0839bfacfb24..5f3ceed19b9a 100644
> --- a/playbooks/roles/gen_tfvars/templates/oci/terraform.tfvars.j2
> +++ b/playbooks/roles/gen_tfvars/templates/oci/terraform.tfvars.j2
> @@ -25,6 +25,7 @@ oci_sparse_volume_device_file_name = "{{ terraform_oci_sparse_volume_device_file
>  ssh_config_pubkey_file = "{{ kdevops_terraform_ssh_config_pubkey_file }}"
>  ssh_config_user = "{{ kdevops_terraform_ssh_config_user }}"
>  ssh_config = "{{ sshconfig }}"
> +ssh_config_port = {{ ansible_cfg_ssh_port }}
>  
>  ssh_config_update = "{{ kdevops_terraform_ssh_config_update | lower }}"
>  ssh_config_use_strict_settings = "{{ kdevops_terraform_ssh_config_update_strict | lower }}"
> diff --git a/playbooks/roles/gen_tfvars/templates/openstack/terraform.tfvars.j2 b/playbooks/roles/gen_tfvars/templates/openstack/terraform.tfvars.j2
> index 3df0e3a4da24..a50468072e59 100644
> --- a/playbooks/roles/gen_tfvars/templates/openstack/terraform.tfvars.j2
> +++ b/playbooks/roles/gen_tfvars/templates/openstack/terraform.tfvars.j2
> @@ -7,6 +7,7 @@ ssh_pubkey_name = "{{ terraform_openstack_ssh_pubkey_name }}"
>  ssh_config_pubkey_file = "{{ kdevops_terraform_ssh_config_pubkey_file }}"
>  ssh_config_user = "{{ kdevops_terraform_ssh_config_user }}"
>  ssh_config = "{{ sshconfig }}"
> +ssh_config_port = {{ ansible_cfg_ssh_port }}
>  
>  ssh_config_update = "{{ kdevops_terraform_ssh_config_update | lower }}"
>  ssh_config_use_strict_settings = "{{ kdevops_terraform_ssh_config_update_strict  | lower }}"
> diff --git a/playbooks/roles/terraform/templates/ssh_config.j2 b/playbooks/roles/terraform/templates/ssh_config.j2
> index 5e8adf0253a1..ba62a2209d4c 100644
> --- a/playbooks/roles/terraform/templates/ssh_config.j2
> +++ b/playbooks/roles/terraform/templates/ssh_config.j2
> @@ -1,7 +1,7 @@
>  Host {{ item.key }} {{ item.value }}
>  	HostName {{ item.value }}
>  	User {{ kdevops_terraform_ssh_config_user }}
> -	Port 22
> +	Port {{ ansible_cfg_ssh_port }}
>  	IdentityFile {{ kdevops_terraform_ssh_config_privkey_file }}
>  {% if ssh_config_kexalgorithms %}
>  	KexAlgorithms {{ ssh_config_kexalgorithms }}
> diff --git a/scripts/update_ssh_config_lambdalabs.py b/scripts/update_ssh_config_lambdalabs.py
> index 5b9ab0aa82e6..265f85c2315b 100755
> --- a/scripts/update_ssh_config_lambdalabs.py
> +++ b/scripts/update_ssh_config_lambdalabs.py
> @@ -11,7 +11,7 @@ from pathlib import Path
>  
>  
>  def update_ssh_config(
> -    action, hostname, ip_address, username, config_file, ssh_key, provider_name
> +    action, hostname, ip_address, username, config_file, ssh_key, provider_name, port=22
>  ):
>      """
>      Update SSH configuration file with Lambda Labs instance details.
> @@ -24,6 +24,7 @@ def update_ssh_config(
>          config_file: SSH config file path
>          ssh_key: Path to SSH private key
>          provider_name: Provider name for comments
> +        port: SSH port number (default: 22)
>      """
>      config_file = os.path.expanduser(config_file)
>      ssh_key = os.path.expanduser(ssh_key)
> @@ -33,7 +34,7 @@ def update_ssh_config(
>  Host {hostname} {ip_address}
>  \tHostName {ip_address}
>  \tUser {username}
> -\tPort 22
> +\tPort {port}
>  \tIdentityFile {ssh_key}
>  \tUserKnownHostsFile /dev/null
>  \tStrictHostKeyChecking no
> @@ -90,7 +91,7 @@ def main():
>      """Main entry point."""
>      if len(sys.argv) < 7:
>          print(
> -            f"Usage: {sys.argv[0]} <action> <hostname> <ip_address> <username> <config_file> <ssh_key> [provider_name]"
> +            f"Usage: {sys.argv[0]} <action> <hostname> <ip_address> <username> <config_file> <ssh_key> [provider_name] [port]"
>          )
>          print("  action: 'update' or 'remove'")
>          print("  hostname: Instance hostname")
> @@ -99,6 +100,7 @@ def main():
>          print("  config_file: SSH config file path")
>          print("  ssh_key: Path to SSH private key")
>          print("  provider_name: Optional provider name (default: 'Lambda Labs')")
> +        print("  port: Optional SSH port (default: 22)")
>          sys.exit(1)
>  
>      action = sys.argv[1]
> @@ -108,9 +110,17 @@ def main():
>      config_file = sys.argv[5]
>      ssh_key = sys.argv[6]
>      provider_name = sys.argv[7] if len(sys.argv) > 7 else "Lambda Labs"
> +    port = int(sys.argv[8]) if len(sys.argv) > 8 else 22
>  
>      update_ssh_config(
> -        action, hostname, ip_address, username, config_file, ssh_key, provider_name
> +        action,
> +        hostname,
> +        ip_address,
> +        username,
> +        config_file,
> +        ssh_key,
> +        provider_name,
> +        port,
>      )
>  
>  
> diff --git a/terraform/aws/main.tf b/terraform/aws/main.tf
> index 949b2febcf0a..0de2e53710cb 100644
> --- a/terraform/aws/main.tf
> +++ b/terraform/aws/main.tf
> @@ -39,8 +39,8 @@ resource "aws_security_group" "kdevops_sec_group" {
>      cidr_blocks = [
>        "0.0.0.0/0",
>      ]
> -    from_port = 22
> -    to_port   = 22
> +    from_port = var.ssh_config_port
> +    to_port   = var.ssh_config_port
>      protocol  = "tcp"
>    }
>  
> @@ -82,6 +82,7 @@ data "template_file" "script_user_data" {
>      user_data_log_dir = var.user_data_log_dir
>      user_data_enabled = var.user_data_enabled
>      ssh_config_user   = var.ssh_config_user
> +    ssh_config_port   = var.ssh_config_port
>      new_hostname      = element(var.kdevops_nodes, count.index),
>    }
>  }
> diff --git a/terraform/azure/main.tf b/terraform/azure/main.tf
> index 8dcead78b5fd..eb609933f2ad 100644
> --- a/terraform/azure/main.tf
> +++ b/terraform/azure/main.tf
> @@ -43,7 +43,7 @@ resource "azurerm_network_security_group" "kdevops_sg" {
>      access                     = "Allow"
>      protocol                   = "Tcp"
>      source_port_range          = "*"
> -    destination_port_range     = "22"
> +    destination_port_range     = tostring(var.ssh_config_port)
>      source_address_prefix      = "*"
>      destination_address_prefix = "*"
>    }
> @@ -89,6 +89,13 @@ resource "azurerm_linux_virtual_machine" "kdevops_vm" {
>    size                            = var.azure_vmsize
>    admin_username                  = var.ssh_config_user
>    disable_password_authentication = true
> +  custom_data = base64encode(templatefile("${path.module}/../scripts/cloud-init.sh", {
> +    user_data_log_dir = "/var/log/kdevops"
> +    user_data_enabled = "yes"
> +    ssh_config_user   = var.ssh_config_user
> +    ssh_config_port   = var.ssh_config_port
> +    new_hostname      = element(var.kdevops_nodes, count.index)
> +  }))
>  
>    os_disk {
>      # Note: yes using the names like the ones below is better however it also
> diff --git a/terraform/gce/main.tf b/terraform/gce/main.tf
> index 816f43098e88..254ecb6a6803 100644
> --- a/terraform/gce/main.tf
> +++ b/terraform/gce/main.tf
> @@ -3,6 +3,19 @@ data "google_compute_image" "kdevops_image" {
>    family  = var.gce_image_family
>  }
>  
> +resource "google_compute_firewall" "kdevops_ssh" {
> +  name    = "kdevops-allow-ssh"
> +  network = "default"
> +
> +  allow {
> +    protocol = "tcp"
> +    ports    = [tostring(var.ssh_config_port)]
> +  }
> +
> +  source_ranges = ["0.0.0.0/0"]
> +  target_tags   = ["kdevops-ssh"]
> +}
> +
>  resource "google_compute_instance" "kdevops_instance" {
>    count        = local.kdevops_num_boxes
>    name         = element(var.kdevops_nodes, count.index)
> @@ -33,7 +46,15 @@ resource "google_compute_instance" "kdevops_instance" {
>      ssh-keys = format("%s:%s", var.ssh_config_user, file(var.ssh_config_pubkey_file))
>    }
>  
> -  metadata_startup_script = "echo hi > /test.txt"
> +  metadata_startup_script = templatefile("${path.module}/../scripts/cloud-init.sh", {
> +    user_data_log_dir = "/var/log/kdevops"
> +    user_data_enabled = "yes"
> +    ssh_config_user   = var.ssh_config_user
> +    ssh_config_port   = var.ssh_config_port
> +    new_hostname      = element(var.kdevops_nodes, count.index)
> +  })
> +
> +  tags = ["kdevops-ssh"]
>  }
>  
>  module "kdevops_compute_disks" {
> diff --git a/terraform/lambdalabs/main.tf b/terraform/lambdalabs/main.tf
> index a78866c7c8c2..1d736f0c503a 100644
> --- a/terraform/lambdalabs/main.tf
> +++ b/terraform/lambdalabs/main.tf
> @@ -88,7 +88,7 @@ resource "null_resource" "ansible_update_ssh_config_hosts" {
>    for_each = var.ssh_config_update ? toset(var.kdevops_nodes) : []
>  
>    provisioner "local-exec" {
> -    command = "python3 ${path.module}/../../scripts/update_ssh_config_lambdalabs.py update ${each.key} ${lambdalabs_instance.kdevops[each.key].ip} ${local.ssh_user} ${var.ssh_config_name} ${var.ssh_config_privkey_file} 'Lambda Labs'"
> +    command = "python3 ${path.module}/../../scripts/update_ssh_config_lambdalabs.py update ${each.key} ${lambdalabs_instance.kdevops[each.key].ip} ${local.ssh_user} ${var.ssh_config_name} ${var.ssh_config_privkey_file} 'Lambda Labs' ${var.ssh_config_port}"
>    }
>  
>    triggers = {
> @@ -113,6 +113,43 @@ resource "null_resource" "remove_ssh_config" {
>    }
>  }
>  
> +# Configure SSH port if not using default port 22
> +resource "null_resource" "configure_ssh_port" {
> +  for_each = var.ssh_config_port != 22 ? toset(var.kdevops_nodes) : []
> +
> +  connection {
> +    type        = "ssh"
> +    host        = lambdalabs_instance.kdevops[each.key].ip
> +    user        = local.ssh_user
> +    port        = 22
> +    private_key = file(pathexpand(var.ssh_config_privkey_file))
> +  }
> +
> +  provisioner "remote-exec" {
> +    inline = [
> +      "echo 'Waiting for system to be ready...'",
> +      "sudo cloud-init status --wait || true",
> +      "echo 'Configuring SSH to listen on port ${var.ssh_config_port}'",
> +      "sudo sed -i '/^[#[:space:]]*Port/d' /etc/ssh/sshd_config",
> +      "echo 'Port ${var.ssh_config_port}' | sudo tee -a /etc/ssh/sshd_config",
> +      "if [ -d /etc/selinux ] && sudo sestatus 2>/dev/null | grep -q 'SELinux status.*enabled'; then if ! command -v semanage >/dev/null 2>&1; then sudo yum install -y policycoreutils-python-utils 2>&1 || sudo dnf install -y policycoreutils-python-utils 2>&1 || true; fi; if command -v semanage >/dev/null 2>&1; then sudo semanage port -a -t ssh_port_t -p tcp ${var.ssh_config_port} 2>&1 || sudo semanage port -m -t ssh_port_t -p tcp ${var.ssh_config_port} 2>&1 || true; fi; fi",
> +      "if command -v firewall-cmd >/dev/null 2>&1 && sudo systemctl is-enabled firewalld >/dev/null 2>&1; then sudo firewall-cmd --permanent --add-port=${var.ssh_config_port}/tcp && sudo firewall-cmd --reload; fi",
> +      "if command -v ufw >/dev/null 2>&1 && sudo systemctl is-active ufw >/dev/null 2>&1; then sudo ufw allow ${var.ssh_config_port}/tcp; fi",
> +      "sudo systemctl restart sshd",
> +      "echo 'SSH port configuration completed'"
> +    ]
> +  }
> +
> +  depends_on = [
> +    lambdalabs_instance.kdevops,
> +    null_resource.ansible_update_ssh_config_hosts
> +  ]
> +
> +  triggers = {
> +    instance_id = lambdalabs_instance.kdevops[each.key].id
> +  }
> +}
> +
>  # Ansible provisioning
>  resource "null_resource" "ansible_provision" {
>    for_each = toset(var.kdevops_nodes)
> @@ -121,6 +158,7 @@ resource "null_resource" "ansible_provision" {
>      type        = "ssh"
>      host        = lambdalabs_instance.kdevops[each.key].ip
>      user        = local.ssh_user
> +    port        = var.ssh_config_port
>      private_key = file(pathexpand(var.ssh_config_privkey_file))
>    }
>  
> @@ -145,7 +183,8 @@ resource "null_resource" "ansible_provision" {
>  
>    depends_on = [
>      lambdalabs_instance.kdevops,
> -    null_resource.ansible_update_ssh_config_hosts
> +    null_resource.ansible_update_ssh_config_hosts,
> +    null_resource.configure_ssh_port
>    ]
>  
>    triggers = {
> diff --git a/terraform/oci/main.tf b/terraform/oci/main.tf
> index 15660aa02614..399a05621ee3 100644
> --- a/terraform/oci/main.tf
> +++ b/terraform/oci/main.tf
> @@ -35,6 +35,13 @@ resource "oci_core_instance" "kdevops_instance" {
>  
>    metadata = {
>      ssh_authorized_keys = file(var.ssh_config_pubkey_file)
> +    user_data = base64encode(templatefile("${path.module}/../scripts/cloud-init.sh", {
> +      user_data_log_dir = "/var/log/kdevops"
> +      user_data_enabled = "yes"
> +      ssh_config_user   = var.ssh_config_user
> +      ssh_config_port   = var.ssh_config_port
> +      new_hostname      = element(var.kdevops_nodes, count.index)
> +    }))
>    }
>  
>    preemptible_instance_config {
> @@ -155,8 +162,8 @@ resource "oci_core_security_list" "kdevops_security_list" {
>      source_type = "CIDR_BLOCK"
>      stateless   = false
>      tcp_options {
> -      min = 22
> -      max = 22
> +      min = var.ssh_config_port
> +      max = var.ssh_config_port
>      }
>    }
>    ingress_security_rules {
> diff --git a/terraform/openstack/main.tf b/terraform/openstack/main.tf
> index 6e31e2f07dd5..c9037ca734f9 100644
> --- a/terraform/openstack/main.tf
> +++ b/terraform/openstack/main.tf
> @@ -19,8 +19,8 @@ resource "openstack_compute_secgroup_v2" "kdevops_security_group" {
>  
>    # SSH
>    rule {
> -    from_port   = 22
> -    to_port     = 22
> +    from_port   = var.ssh_config_port
> +    to_port     = var.ssh_config_port
>      ip_protocol = "tcp"
>      cidr        = "0.0.0.0/0"
>    }
> @@ -62,6 +62,13 @@ resource "openstack_compute_instance_v2" "kdevops_instances" {
>    flavor_name     = var.flavor_name
>    key_pair        = var.ssh_pubkey_name
>    security_groups = [openstack_compute_secgroup_v2.kdevops_security_group.name]
> +  user_data = templatefile("${path.module}/../scripts/cloud-init.sh", {
> +    user_data_log_dir = "/var/log/kdevops"
> +    user_data_enabled = "yes"
> +    ssh_config_user   = var.ssh_config_user
> +    ssh_config_port   = var.ssh_config_port
> +    new_hostname      = element(var.kdevops_nodes, count.index)
> +  })
>    network {
>      name          = var.public_network_name
>    }
> diff --git a/terraform/scripts/cloud-init.sh b/terraform/scripts/cloud-init.sh
> index 926afe99faf3..86c8a67ec13a 100755
> --- a/terraform/scripts/cloud-init.sh
> +++ b/terraform/scripts/cloud-init.sh
> @@ -49,7 +49,49 @@ if [ "$USERDATA_ENABLED" != "yes" ]; then
>  fi
>  
>  run_cmd_admin echo "cloud-init: kdevops script user data processing enabled"
> -run_cmd_admin echo "Nothing to do..."
> +
> +# Configure SSH port if not using default port 22
> +SSH_PORT="${ssh_config_port}"
> +if [ "$SSH_PORT" != "22" ]; then
> +	run_cmd_admin echo "Configuring SSH to listen on port $SSH_PORT"
> +
> +	# Update sshd_config to use alternate port
> +	run_cmd_admin sed -i '/^[#[:space:]]*Port/d' /etc/ssh/sshd_config
> +	echo "Port $SSH_PORT" | run_cmd_admin tee -a /etc/ssh/sshd_config > /dev/null
> +
> +	# Configure SELinux if present
> +	if [ -d /etc/selinux ] && sestatus 2>/dev/null | grep -q "SELinux status.*enabled"; then
> +		# Install semanage if not available (RHEL/CentOS/Rocky/AlmaLinux)
> +		if ! command -v semanage >/dev/null 2>&1; then
> +			run_cmd_admin yum install -y policycoreutils-python-utils 2>&1 || run_cmd_admin dnf install -y policycoreutils-python-utils 2>&1 || true
> +		fi
> +
> +		# Try to add the port first, if it fails (already exists), modify it
> +		if command -v semanage >/dev/null 2>&1; then
> +			run_cmd_admin semanage port -a -t ssh_port_t -p tcp $SSH_PORT 2>&1 || run_cmd_admin semanage port -m -t ssh_port_t -p tcp $SSH_PORT 2>&1 || true
> +			run_cmd_admin echo "SELinux port configuration completed"
> +		else
> +			run_cmd_admin echo "WARNING: semanage not available, SELinux may block port $SSH_PORT"
> +		fi
> +	fi
> +
> +	# Configure firewalld if present and enabled
> +	if command -v firewall-cmd >/dev/null 2>&1 && systemctl is-enabled firewalld >/dev/null 2>&1; then
> +		run_cmd_admin firewall-cmd --permanent --add-port=$SSH_PORT/tcp
> +		run_cmd_admin firewall-cmd --reload
> +	fi
> +
> +	# Configure ufw if present and active
> +	if command -v ufw >/dev/null 2>&1 && systemctl is-active ufw >/dev/null 2>&1; then
> +		run_cmd_admin ufw allow $SSH_PORT/tcp
> +	fi
> +
> +	# Restart sshd to apply changes
> +	run_cmd_admin systemctl restart sshd
> +	run_cmd_admin echo "SSH port configuration completed"
> +else
> +	run_cmd_admin echo "Using default SSH port 22, no configuration needed"
> +fi
>  
>  # Add more functionality below if you see fit. Be sure to use a variable
>  # to allow to easily enable / disable each mechanism.
> diff --git a/terraform/shared.tf b/terraform/shared.tf
> index 88e87a27378d..488becd0f797 100644
> --- a/terraform/shared.tf
> +++ b/terraform/shared.tf
> @@ -44,6 +44,12 @@ variable "ssh_config_kexalgorithms" {
>    default     = ""
>  }
>  
> +variable "ssh_config_port" {
> +  description = "SSH port to use for remote connections and firewall rules"
> +  type        = number
> +  default     = 22
> +}
> +
>  variable "private_net_enabled" {
>    description = "Is the private network enabled?"
>    default     = "false"


-- 
Chuck Lever