All of lore.kernel.org
 help / color / mirror / Atom feed
From: cel@kernel.org
To: <kdevops@lists.linux.dev>
Cc: Chuck Lever <chuck.lever@oracle.com>,
	Luis Chamberlain <mcgrof@kernel.org>
Subject: [PATCH v2 10/12] terraform: Add ssh hosts to ~/.ssh/config_kdevops_{{ sha1sum }}
Date: Wed,  5 Feb 2025 10:52:50 -0500	[thread overview]
Message-ID: <20250205155252.1317763-11-cel@kernel.org> (raw)
In-Reply-To: <20250205155252.1317763-1-cel@kernel.org>

From: Chuck Lever <chuck.lever@oracle.com>

The fixed update_ssh_config module is still not removing ssh Host
configuration information with "make destroy".

Also, we want to have more control over how the control host's
ssh config is managed. Updating a separate terraform module is
getting awkward.

Let's replace the independent terraform module that handles ssh
configuration with a playbook that operates the same as guestfs:
the host config is stuffed into a common file under ~/.ssh that
is included in ~/.ssh/config, and is easily located and deleted
by "make destroy".

XXX: I'm not 100% sold on this organization: it might be better
to fold the new playbook into scripts/bringup_terraform.sh
somehow.

Suggested-by: Luis Chamberlain <mcgrof@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
 playbooks/add_ssh_hosts_terraform.yml         |  5 +++
 .../add_ssh_hosts_terraform/defaults/main.yml |  2 ++
 .../add_ssh_hosts_terraform/tasks/main.yml    | 33 +++++++++++++++++++
 .../templates/ssh_config.j2                   | 15 +++++++++
 scripts/terraform.Makefile                    |  5 +++
 terraform/aws/output.tf                       |  7 ++++
 terraform/azure/output.tf                     |  8 +++++
 terraform/gce/output.tf                       |  8 +++++
 terraform/oci/output.tf                       |  9 +++++
 terraform/openstack/output.tf                 |  7 ++++
 10 files changed, 99 insertions(+)
 create mode 100644 playbooks/add_ssh_hosts_terraform.yml
 create mode 100644 playbooks/roles/add_ssh_hosts_terraform/defaults/main.yml
 create mode 100644 playbooks/roles/add_ssh_hosts_terraform/tasks/main.yml
 create mode 100644 playbooks/roles/add_ssh_hosts_terraform/templates/ssh_config.j2
 create mode 100644 terraform/oci/output.tf

diff --git a/playbooks/add_ssh_hosts_terraform.yml b/playbooks/add_ssh_hosts_terraform.yml
new file mode 100644
index 000000000000..b5ef86d09ac9
--- /dev/null
+++ b/playbooks/add_ssh_hosts_terraform.yml
@@ -0,0 +1,5 @@
+---
+- hosts: all
+  gather_facts: false
+  roles:
+    - role: add_ssh_hosts_terraform
diff --git a/playbooks/roles/add_ssh_hosts_terraform/defaults/main.yml b/playbooks/roles/add_ssh_hosts_terraform/defaults/main.yml
new file mode 100644
index 000000000000..33bd00e6d1a4
--- /dev/null
+++ b/playbooks/roles/add_ssh_hosts_terraform/defaults/main.yml
@@ -0,0 +1,2 @@
+---
+ssh_config_kexalgorithms: ""
diff --git a/playbooks/roles/add_ssh_hosts_terraform/tasks/main.yml b/playbooks/roles/add_ssh_hosts_terraform/tasks/main.yml
new file mode 100644
index 000000000000..d10db0175294
--- /dev/null
+++ b/playbooks/roles/add_ssh_hosts_terraform/tasks/main.yml
@@ -0,0 +1,33 @@
+---
+- name: Retrieve the public_ip_map from terraform
+  run_once: true
+  ansible.builtin.command:
+    chdir: "{{ topdir_path }}/terraform/{{ kdevops_terraform_provider }}"
+    cmd: "terraform output -json public_ip_map"
+  register: terraform_output
+  changed_when: false
+
+- name: Convert the public_ip_map into a dictionary
+  run_once: true
+  ansible.builtin.set_fact:
+    public_ip_map: "{{ terraform_output.stdout | from_json }}"
+
+- name: Insert or update the controller's ssh Host entry for {{ inventory_hostname }}
+  vars:
+    hostname: "{{ inventory_hostname }}"
+    ipaddr: "{{ public_ip_map[inventory_hostname] }}"
+    port: "22"
+    user: "{{ kdevops_terraform_ssh_config_user }}"
+    sshkey: "{{ sshdir }}/{{ kdevops_terraform_ssh_config_pubkey_file|basename|replace('.pub', '') }}"
+    strict: "{{ kdevops_terraform_ssh_config_update_strict|bool }}"
+    kexalgorithms: "{{ ssh_config_kexalgorithms }}"
+  throttle: 1
+  ansible.builtin.blockinfile:
+    block: "{{ lookup('template', 'ssh_config.j2') }}"
+    create: true
+    dest: "{{ kdevops_ssh_config }}"
+    insertafter: "EOF"
+    marker: "# {mark} host configuration for {{ inventory_hostname }}"
+    marker_begin: "begin"
+    marker_end: "end"
+    mode: "u=rw,g=r,o=r"
diff --git a/playbooks/roles/add_ssh_hosts_terraform/templates/ssh_config.j2 b/playbooks/roles/add_ssh_hosts_terraform/templates/ssh_config.j2
new file mode 100644
index 000000000000..f212e6e48607
--- /dev/null
+++ b/playbooks/roles/add_ssh_hosts_terraform/templates/ssh_config.j2
@@ -0,0 +1,15 @@
+Host {{ hostname }} {{ ipaddr }}
+	HostName {{ ipaddr }}
+	User {{ user }}
+	Port {{ port }}
+	IdentityFile {{ sshkey }}
+{% if kexalgorithms %}
+	KexAlgorithms {{ kexalgorithms }}
+{% endif %}
+{% if strict %}
+	UserKnownHostsFile /dev/null
+	StrictHostKeyChecking no
+	PasswordAuthentication no
+	IdentitiesOnly yes
+	LogLevel FATAL
+{% endif %}
diff --git a/scripts/terraform.Makefile b/scripts/terraform.Makefile
index b4543d2561fb..1e86096717cb 100644
--- a/scripts/terraform.Makefile
+++ b/scripts/terraform.Makefile
@@ -165,6 +165,11 @@ ANSIBLE_EXTRA_ARGS += $(TERRAFORM_EXTRA_VARS)
 
 bringup_terraform:
 	$(Q)$(TOPDIR)/scripts/bringup_terraform.sh
+	$(Q)ansible-playbook $(ANSIBLE_VERBOSE) --connection=local \
+		--inventory hosts \
+		playbooks/add_ssh_hosts_terraform.yml \
+		--extra-vars=@./extra_vars.yaml \
+		-e 'ansible_python_interpreter=/usr/bin/python3'
 
 destroy_terraform:
 	$(Q)$(TOPDIR)/scripts/destroy_terraform.sh
diff --git a/terraform/aws/output.tf b/terraform/aws/output.tf
index 6ff195be2515..cb8cab4afcdd 100644
--- a/terraform/aws/output.tf
+++ b/terraform/aws/output.tf
@@ -25,3 +25,10 @@ output "login_using" {
   value = data.null_data_source.group_hostnames_and_ips.*.outputs
 }
 
+# Each provider's output.tf needs to define a public_ip_map. This
+# map is used to build the Ansible controller's ssh configuration.
+# Each map entry contains the node's hostname and public IP address.
+output "public_ip_map" {
+  description = "The public IP addresses assigned to each instance"
+  value = "${zipmap(var.kdevops_nodes[*], aws_eip.kdevops_eip[*].public_ip)}"
+}
diff --git a/terraform/azure/output.tf b/terraform/azure/output.tf
index 5a2654970011..a8e32b605a47 100644
--- a/terraform/azure/output.tf
+++ b/terraform/azure/output.tf
@@ -37,3 +37,11 @@ data "null_data_source" "group_hostnames_and_ips" {
 output "login_using" {
   value = data.null_data_source.group_hostnames_and_ips.*.outputs
 }
+
+# Each provider's output.tf needs to define a public_ip_map. This
+# map is used to build the Ansible controller's ssh configuration.
+# Each map entry contains the node's hostname and public IP address.
+output "public_ip_map" {
+  description = "The public IP addresses assigned to each instance"
+  value = "${zipmap(var.kdevops_nodes[*], azurerm_public_ip.kdevops_publicip[*].name)}"
+}
diff --git a/terraform/gce/output.tf b/terraform/gce/output.tf
index 7b96c829173b..b95667cc7efd 100644
--- a/terraform/gce/output.tf
+++ b/terraform/gce/output.tf
@@ -24,3 +24,11 @@ data "null_data_source" "group_hostnames_and_ips" {
 output "login_using" {
   value = data.null_data_source.group_hostnames_and_ips.*.outputs
 }
+
+# Each provider's output.tf needs to define a public_ip_map. This
+# map is used to build the Ansible controller's ssh configuration.
+# Each map entry contains the node's hostname and public IP address.
+output "public_ip_map" {
+  description = "The public IP addresses assigned to each instance"
+  value = "${zipmap(var.kdevops_nodes[*], local.ipv4s[*])}"
+}
diff --git a/terraform/oci/output.tf b/terraform/oci/output.tf
new file mode 100644
index 000000000000..83a85a388055
--- /dev/null
+++ b/terraform/oci/output.tf
@@ -0,0 +1,9 @@
+# All generic output goes here
+
+# Each provider's output.tf needs to define a public_ip_map. This
+# map is used to build the Ansible controller's ssh configuration.
+# Each map entry contains the node's hostname and public IP address.
+output "public_ip_map" {
+  description = "The public IP addresses assigned to each instance"
+  value = "${zipmap(var.kdevops_nodes[*], aws_eip.kdevops_eip[*].public_ip)}"
+}
diff --git a/terraform/openstack/output.tf b/terraform/openstack/output.tf
index 148343561ae5..aff44d1b45f9 100644
--- a/terraform/openstack/output.tf
+++ b/terraform/openstack/output.tf
@@ -16,3 +16,10 @@ output "kdevops_hosts_and_ipv4" {
   value = data.null_data_source.group_hostnames_and_ips.*.outputs
 }
 
+# Each provider's output.tf needs to define a public_ip_map. This
+# map is used to build the Ansible controller's ssh configuration.
+# Each map entry contains the node's hostname and public IP address.
+output "public_ip_map" {
+  description = "The public IP addresses assigned to each instance"
+  value = "${zipmap(var.kdevops_nodes[*], openstack_compute_instance_v2.kdevops_instances[*].access_ip_v4)}"
+}
-- 
2.48.1


  parent reply	other threads:[~2025-02-05 15:53 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-05 15:52 [PATCH v2 00/12] Replace terraform update_ssh_config module cel
2025-02-05 15:52 ` [PATCH v2 01/12] guestfs: Rename the update_ssh_config_guestfs role cel
2025-02-05 15:52 ` [PATCH v2 02/12] update_ssh_config: Use {{ sshconfig }} instead of raw path cel
2025-02-05 15:52 ` [PATCH v2 03/12] update_ssh_config: Fix ansible-lint nits cel
2025-02-05 15:52 ` [PATCH v2 04/12] update_ssh_config: Run update_ssh_config during "make deps" cel
2025-02-05 15:52 ` [PATCH v2 05/12] update_ssh_config: Add tags to steps cel
2025-02-05 15:52 ` [PATCH v2 06/12] ssh.Makefile: Generate an sshdir variable cel
2025-02-05 15:52 ` [PATCH v2 07/12] update_ssh_config: make Include directive follow ssh config directory cel
2025-02-06 19:58   ` Chuck Lever
2025-02-05 15:52 ` [PATCH v2 08/12] ssh.Makefile: Define a kdevops_ssh_config variable cel
2025-02-05 17:42   ` Luis Chamberlain
2025-02-06  2:36     ` Chuck Lever
2025-02-05 15:52 ` [PATCH v2 09/12] update_ssh_config: Add always-run ssh clean-up steps cel
2025-02-05 15:52 ` cel [this message]
2025-02-05 15:52 ` [PATCH v2 11/12] terraform: "make mrproper" should remove terraform/*/.terraform cel
2025-02-05 15:52 ` [PATCH v2 12/12] terraform: Remove the terrraform update_ssh_config module cel
2025-02-05 17:44 ` [PATCH v2 00/12] Replace terraform " Luis Chamberlain

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250205155252.1317763-11-cel@kernel.org \
    --to=cel@kernel.org \
    --cc=chuck.lever@oracle.com \
    --cc=kdevops@lists.linux.dev \
    --cc=mcgrof@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.