Ansible with jump host
Welcome
Long time no sea. It's not a typo last time when I saw the see was in September in Greece. Almost the same thing I can say about Ansible. The last time when I used this tool for resolving real problems was more-less 2years ago. To be honest, during this period Ansible becomes (in my mind at least) just another boring and old-fashioned tool. Who is using Ansible if we have containers, Kubernetes Engines and Serverless? Only boring people. However, do you know who does not use Ansible? People without personal life or interesting problem to solve. I'm boring...
Problem
As you can assume I'm not an Ansible uber-master, I know most of the bases, but still, sometimes I stuck with some small, hidden option or strange use case a bit too long. That will be one of this use-case. Run Ansible through jump server.
Scenario
I have a VM. Brand new and fresh machine with some awesome hardware - let's say GPU monster for machine learning processes. It's based in some office. No static IP. I can connect to this machine via SSH Tunneling through another machine. How to make the connection easier?
SSH config
If You wondering why Linux user don't use tools like MobaXterm, ~/.ssh/config
is the answer. Basic config will looks like that:
1Host test-3sky-dev
2 # test, Suse
3 HostName 3.22.11.33
4 User kuba
5 Port 31
6 IdentityFile ~/.ssh/id_rsa_xy
With that I can only type ssh test-3sky-dev
and buum I'm on my test VM. Cool.
Add jump host
For our case let's assume that I can access monster-3sky-dev
only from test-3sky-dev
. How to do that? Another simple example.
1Host test-3sky-dev
2 # test, Suse
3 HostName 3.22.11.33
4 User kuba
5 Port 31
6 IdentityFile ~/.ssh/id_rsa_xy
7
8Host monster-3sky-dev
9 # prod, ubuntu
10 HostName 12.22.11.33
11 User kuba
12 Port 45
13 ProxyJump test-3sky-dev
Authentication
I like to avoid password authentication so, let's use ssh-copy-id
1# on test-3sky-dev machine
2ssh-keygen -t rsa -b 4096 -C "test-3sky-dev"
3ssh-copy-id -i ~/.ssh/id_rsa_yx.pub kuba@12.22.11.33 -p 45
And configure `~/.ssh/config` on my jump station
1Host monster-3sky-dev
2 HostName 12.22.11.33
3 User kuba
4 Port 45
5 IdentityFile ~/.ssh/id_rsa_yx
Finally
Just run from my workstation - sweet.
1ssh monster-3sky-dev
Implementation
As you can see I can connect to VM via SSH Tunneling, it was simple and rather fast. Now integration with Ansible. Let's write some super simple playbook, like:
1---
2- name: ADD NEW USER
3 gather_facts: false
4 user: kuba
5 hosts: monster-3sky-dev
6 become: yes
7 vars:
8 user: "adam"
9
10 tasks:
11 - name: Ensure group "{{ user }}" exists
12 ansible.builtin.group:
13 name: "{{ user }}"
14 state: present
15
16 - name: Add the user "{{ user }}"
17 ansible.builtin.user:
18 name: "{{ user }}"
19 shell: /bin/bash
20 groups:
21 - "{{ user }}"
22 - docker
23 append: yes
24 home: /home/{{ user }}
25 password: "{{ 'password' | password_hash('sha512') }}"
26 update_password: on_create
27
28 - name: Creat home dirs
29 ansible.builtin.file:
30 path: "{{ item }}"
31 state: directory
32 mode: '0755'
33 owner: "{{ user }}"
34 group: "{{ user }}"
35 loop:
36 - /home/{{ user }}
37 - /home/{{ user }}/bin
38 - /home/{{ user }}/tools
Now I need to provide only differences between normal host, and host behind the firewall.
Look on my inventory file:
1[gpu]
2monster-3sky-dev ansible_python_interpreter=/usr/bin/python3
There is no IP. And that's the point. While executing the ansible-playbook
command I need to specify one environment variable - ANSIBLE_SSH_ARGS
. And that is how it looks:
1ANSIBLE_SSH_ARGS="-F /home/kuba/.ssh/config" ansible monster-3sky-dev -m ping -i host.ini
2monster-3sky-dev | SUCCESS => {
3 "changed": false,
4 "ping": "pong"
5}
One important thing. Hostname from inventory file needs to match with Host from `.ssh/config` file.
How to run a playbook? In the almost same way.
1ANSIBLE_SSH_ARGS="-F /home/kuba/.ssh/config" ansible-playbook add_users/add_user.yaml -i host.ini
Summary
OK, so that is it. Nothing very fancy, but It takes me a while to find the right solution for me. Also is one of these things which are worth working with. No more need to googling the solution I have it here. This article was written in org-mode, then converted into Hugo MD file. That was an interesting adventure, especially when Emacs become my main tool as I said. Ah and OpenSuse. Recently I had some issue with Fedora related to dns-resolver. Since the beginning of March, I'm a happy user of OpenSuse Tumbleweed and I need to say it's an awesome distro. Something between Archlinux(it's rolling release system) and Fedora(easy to use, and stable). Maybe some longe review? I'm not sure, but until now I'm super happy with SUSE.