From patchwork Fri Jan 31 20:19:31 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13955732 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 547EA482EB for ; Fri, 31 Jan 2025 20:19:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738354778; cv=none; b=SWcxuS/UZNgCQSS2LLi/uR/L/NbgtxtLSY94Gx1Y8815daniAVkp3qq81C53X7La/YlyLciA94oZ8TJJW8EY67M2YlCzzEq91k+v8TDO0zZ7YlNDkyc1wIj31FoaSvZn+GGXoLXYs5O4TAoL0PlrNwtuPtsPL9RUbJBho871wIU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738354778; c=relaxed/simple; bh=nAJCyqielSVXeW0LEsPkXeSftLvAwQv7nwtygy9jJ5Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sg7/LxZqS7xthKInW0Kwmmtx15k//lIYi2AYc2I4clvM9mZ+T4ioa2lkoxUSTefdW9IKy5H7BsV2kSOXNBYY9WeTEp4cUc7lwVQNRrZcNwdLYTEhICOsQ30W5TZ1R9wk/9z6ilwpaQ+r0ThSN2WmY7q3NGTaX4FersYqZubxlMU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=dSWqvHJ+; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="dSWqvHJ+" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C77AAC4CEE1; Fri, 31 Jan 2025 20:19:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1738354778; bh=nAJCyqielSVXeW0LEsPkXeSftLvAwQv7nwtygy9jJ5Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dSWqvHJ+7bGbP1ZS3a+Y+EoXIzd80++/ziqIUO2sB6ZNVTvKfPq1XxFtolONnW9IN HRzz4Nw781UNhN2NbePBaKnxvVxDlfmuB/Cw2tVxNPnUB/jbZE4wkVR1jDovS5An+c UaPqZpDUsLJCQ1i5E8r9OCJt/6j3/zUrBUSXtLJtTL0cme5flx3tJpwPLvJJay8AQE CbmmJFSnUiCiJRpJD0F1QXsf/cNK+BmjPONf111hNN7iBKa3HSpZCEndq3xo4XEo4/ YTn9l5GrL+BUotdfLBW0tAkMmTaDT29dbsnmnNCTGEUTIN0EB83MS3wVWh5Ci5f0+e ZzH2WbWzSMlRQ== From: cel@kernel.org To: Cc: Chuck Lever , Luis Chamberlain Subject: [RFC PATCH 3/4] terraform: Add ssh hosts to ~/.ssh/config_kdevops_{{ sha1sum }} Date: Fri, 31 Jan 2025 15:19:31 -0500 Message-ID: <20250131201932.449083-4-cel@kernel.org> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250131201932.449083-1-cel@kernel.org> References: <20250131201932.449083-1-cel@kernel.org> Precedence: bulk X-Mailing-List: kdevops@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Chuck Lever 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 Signed-off-by: Chuck Lever --- playbooks/add_ssh_hosts_terraform.yml | 5 ++ .../add_ssh_hosts_terraform/defaults/main.yml | 2 + .../add_ssh_hosts_terraform/tasks/main.yml | 57 +++++++++++++++++++ .../templates/ssh_config.j2 | 15 +++++ scripts/terraform.Makefile | 5 ++ terraform/aws/output.tf | 7 +++ 6 files changed, 91 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 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..4d85e29c596b --- /dev/null +++ b/playbooks/roles/add_ssh_hosts_terraform/tasks/main.yml @@ -0,0 +1,57 @@ +--- +- name: Set the pathname of the control host's .ssh directory + delegate_to: localhost + run_once: true + ansible.builtin.set_fact: + sshdir: "{{ lookup('ansible.builtin.env', 'HOME') }}/.ssh" + +- name: Set the pathname of the ephemeral ssh config file + delegate_to: localhost + run_once: true + ansible.builtin.set_fact: + host_config: "{{ sshdir }}/config_kdevops_{{ topdir_path_sha256sum }}" + when: + - topdir_path_sha256sum is defined + +- name: Set the pathname of the ephemeral ssh config file + delegate_to: localhost + run_once: true + ansible.builtin.set_fact: + host_config: "{{ sshdir }}/config_kdevops_{{ kdevops_host_prefix }}" + when: + - topdir_path_sha256sum is not defined + +- name: Retrieve the public_ip_map + delegate_to: localhost + 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: Build public_ip_map dict + delegate_to: localhost + run_once: true + ansible.builtin.set_fact: + public_ip_map: "{{ terraform_output.stdout | from_json }}" + +- name: Insert or update a ssh Host entry on the control host for the target node + 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: "{{ host_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 58eadd9cd9a0..fd9716887ac9 100644 --- a/scripts/terraform.Makefile +++ b/scripts/terraform.Makefile @@ -163,6 +163,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)}" +}