diff --git a/infrastructure/create-resources/ansible/inventory/group_vars/all.yml b/infrastructure/create-resources/ansible/inventory/group_vars/all.yml index 4132986..9039b33 100644 --- a/infrastructure/create-resources/ansible/inventory/group_vars/all.yml +++ b/infrastructure/create-resources/ansible/inventory/group_vars/all.yml @@ -2,6 +2,14 @@ k3s_version: v1.22.3+k3s1 ansible_user: root systemd_dir: /etc/systemd/system +systemd_network_dir: /etc/systemd/network master_ip: "{{ hostvars[groups['serverctl_master_hosts'][0]]['ansible_host'] | default(groups['serverctl_master_hosts'][0]) }}" extra_server_args: "" extra_agent_args: "" + +ansible_become_method: su + +ufw_enabled: true + +wireguard_mask_bits: 24 +wireguard_port: 51871 \ No newline at end of file diff --git a/infrastructure/create-resources/ansible/inventory/hosts.cfg b/infrastructure/create-resources/ansible/inventory/hosts.cfg new file mode 100755 index 0000000..8100e2b --- /dev/null +++ b/infrastructure/create-resources/ansible/inventory/hosts.cfg @@ -0,0 +1,18 @@ +[serverctl_master_hosts] + +[serverctl_node_hosts] + +[serverctl_mesh_nodes] +65.21.50.146 ansible_host=65.21.50.146 wireguard_ip=192.168.0.1 +65.21.251.3 ansible_host=65.21.251.3 wireguard_ip=192.168.0.2 +65.21.255.102 ansible_host=65.21.255.102 wireguard_ip=192.168.0.3 +95.216.162.16 ansible_host=95.216.162.16 wireguard_ip=192.168.0.4 + +[serverctl_mesh_nodes:vars] +pipelining=true +ansible_ssh_user=root +ansible_ssh_port=22 + +[serverctl_cluster:children] +serverctl_master_hosts +serverctl_node_hosts diff --git a/infrastructure/create-resources/ansible/ping.yml b/infrastructure/create-resources/ansible/ping.yml new file mode 100644 index 0000000..a633e2b --- /dev/null +++ b/infrastructure/create-resources/ansible/ping.yml @@ -0,0 +1,7 @@ +--- +- hosts: serverctl_mesh_nodes + gather_facts: yes + tasks: + - name: ping + command: "ping -c3 {{ hostvars[item].wireguard_ip}}" + with_items: "{{groups['all']}}" diff --git a/infrastructure/create-resources/ansible/roles/wireguard/mesh/handlers/main.yml b/infrastructure/create-resources/ansible/roles/wireguard/mesh/handlers/main.yml new file mode 100644 index 0000000..1e0813c --- /dev/null +++ b/infrastructure/create-resources/ansible/roles/wireguard/mesh/handlers/main.yml @@ -0,0 +1,7 @@ +--- +- name: systemd network restart + service: + name: systemd-networkd + state: restarted + enabled: yes + become: yes \ No newline at end of file diff --git a/infrastructure/create-resources/ansible/roles/wireguard/mesh/tasks/main.yml b/infrastructure/create-resources/ansible/roles/wireguard/mesh/tasks/main.yml new file mode 100644 index 0000000..f96cf18 --- /dev/null +++ b/infrastructure/create-resources/ansible/roles/wireguard/mesh/tasks/main.yml @@ -0,0 +1,128 @@ +--- +- name: update packages + apt: + update_cache: yes + cache_valid_time: 3600 + become: yes + + +- name: install ufw + apt: + name: ufw + state: present + become: yes + when: ufw_enabled + +- name: Allow SSH in UFW + ufw: + rule: allow + port: "{{ ansible_ssh_port }}" + proto: tcp + become: yes + when: ufw_enabled + +- name: Set ufw logging + ufw: + logging: "on" + become: yes + when: ufw_enabled + +- name: inter-node Wireguard UFW connectivity + ufw: + rule: allow + src: "{{ hostvars[item].wireguard_ip }}" + with_items: "{{ groups['all'] }}" + become: yes + when: ufw_enabled and item != inventory_hostname + +- name: Reject everything and enable UFW + ufw: + state: enabled + policy: reject + log: yes + become: yes + when: ufw_enabled + +- name: enable and persist ip forwarding + sysctl: + name: net.ipv4.ip_forward + value: "1" + state: present + sysctl_set: yes + reload: yes + +- name: install wireguard + apt: + name: wireguard + state: present + become: yes + +- name: generate wireguard keypair + shell: wg genkey | tee /etc/wireguard/privatekey | wg pubkey | tee /etc/wireguard/publickey + args: + creates: /etc/wireguard/privatekey + become: yes + +- name: register private key + shell: cat /etc/wireguard/privatekey + register: wireguard_private_key + changed_when: false + become: yes + +- name: register public key + shell: cat /etc/wireguard/publickey + register: wireguard_public_key + changed_when: false + become: yes + +- name: generate preshared keypair + shell: "wg genpsk > /etc/wireguard/psk-{{item}}" + args: + creates: "/etc/wireguard/psk-{{item}}" + when: inventory_hostname < item + with_items: "{{groups['serverctl_mesh_nodes']}}" + become: yes + +- name: register preshared key + shell: "cat /etc/wireguard/psk-{{item}}" + register: wireguard_preshared_key + changed_when: false + when: inventory_hostname < item + with_items: "{{groups['serverctl_mesh_nodes']}}" + become: yes + +- name: message preshared keys + set_fact: "wireguard_preshared_keys={{wireguard_preshared_keys|default({}) | combine({item.item: item.stdout})}}" + when: item.skipped is not defined + with_items: "{{wireguard_preshared_key.results}}" + become: yes + +- name: Setup wgserverctl0 device + template: + src: 'systemd.netdev' + dest: '{{systemd_network_dir}}/99-wg0.netdev' + owner: root + group: systemd-network + mode: 0640 + become: yes + notify: systemd network restart + +- name: Setup wgserverctl0 network + template: + src: 'systemd.network' + dest: "{{systemd_network_dir}}/99-wg0.network" + owner: root + group: systemd-network + mode: 0640 + become: yes + notify: systemd network restart + +#- name: Start and enalbe wireguard on book +# systemd: +# name: wg-quick@wgserverctl0 +# enabled: yes +# state: started + +#- debug: msg="{{item.1}} - {{ (wireguard_base_ipv4|ipaddr(item.0 + 1)) }}" +# with_indexed_items: "{{groups.serverctl_mesh_nodes}}" + diff --git a/infrastructure/create-resources/ansible/roles/wireguard/mesh/templates/systemd.netdev b/infrastructure/create-resources/ansible/roles/wireguard/mesh/templates/systemd.netdev new file mode 100644 index 0000000..53d16ca --- /dev/null +++ b/infrastructure/create-resources/ansible/roles/wireguard/mesh/templates/systemd.netdev @@ -0,0 +1,20 @@ +[NetDev] +Name=wg0 +Kind=wireguard +Description=WireGuard tunnel wg0 + +[WireGuard] +ListenPort={{ wireguard_port }} +PrivateKey={{ wireguard_private_key.stdout }} + +{% for peer in groups['serverctl_mesh_nodes'] %} +{% if peer != inventory_hostname %} + +[WireGuardPeer] +PublicKey={{ hostvars[peer].wireguard_public_key.stdout }} +PresharedKey={{ wireguard_preshared_keys[peer] if inventory_hostname < peer else hostvars[peer].wireguard_preshared_keys[inventory_hostname] }} +AllowedIPs={{ hostvars[peer].wireguard_ip }}/32 +Endpoint={{ hostvars[peer].ansible_host }}:{{ wireguard_port }} +PersistentKeepalive=25 +{% endif %} +{% endfor %} \ No newline at end of file diff --git a/infrastructure/create-resources/ansible/roles/wireguard/mesh/templates/systemd.network b/infrastructure/create-resources/ansible/roles/wireguard/mesh/templates/systemd.network new file mode 100644 index 0000000..c282bf9 --- /dev/null +++ b/infrastructure/create-resources/ansible/roles/wireguard/mesh/templates/systemd.network @@ -0,0 +1,5 @@ +[Match] +Name=wg0 + +[Network] +Address={{ wireguard_ip }}/{{ wireguard_mask_bits }} \ No newline at end of file diff --git a/infrastructure/create-resources/ansible/site.yml b/infrastructure/create-resources/ansible/site.yml index 3880cd7..0b62540 100644 --- a/infrastructure/create-resources/ansible/site.yml +++ b/infrastructure/create-resources/ansible/site.yml @@ -9,6 +9,13 @@ become: yes roles: - role: "./k3s/master" + +- hosts: serverctl_mesh_nodes + become: yes + gather_facts: yes + roles: + - role: './wireguard/mesh' + #- hosts: serverctl_node_hosts # become: yes # roles: diff --git a/infrastructure/create-resources/hcloud.tf b/infrastructure/create-resources/hcloud.tf index 2d08201..493073d 100644 --- a/infrastructure/create-resources/hcloud.tf +++ b/infrastructure/create-resources/hcloud.tf @@ -1,4 +1,3 @@ - variable "serverctl_master_count" { default = 0 } @@ -7,6 +6,9 @@ variable "serverctl_node_count" { default = 0 } +variable "serverctl_mesh_count" { + default = 4 +} resource "hcloud_placement_group" "serverctl_master" { name = "serverctl_master_group" @@ -18,7 +20,7 @@ resource "hcloud_server" "serverctl_master" { name = "serverctl-master-${count.index}" image = "debian-11" server_type = "cx11" - ssh_keys = [ + ssh_keys = [ var.hcloud_serverctl_ssh_key_id ] placement_group_id = hcloud_placement_group.serverctl_master.id @@ -50,7 +52,7 @@ resource "hcloud_server" "serverctl_node" { name = "serverctl-node-${count.index}" image = "debian-11" server_type = "cx11" - ssh_keys = [ + ssh_keys = [ var.hcloud_serverctl_ssh_key_id ] placement_group_id = hcloud_placement_group.serverctl_node.id @@ -72,11 +74,44 @@ resource "hcloud_server" "serverctl_node" { } } +resource "hcloud_placement_group" "serverctl_mesh" { + name = "serverctl_mesh_group" + type = "spread" +} + +resource "hcloud_server" "serverctl_mesh" { + count = var.serverctl_mesh_count + name = "serverctl-mesh-${count.index}" + image = "debian-11" + server_type = "cx11" + ssh_keys = [ + var.hcloud_serverctl_ssh_key_id + ] + placement_group_id = hcloud_placement_group.serverctl_mesh.id + + + lifecycle { + create_before_destroy = true + } + + provisioner "remote-exec" { + inline = ["sudo apt update", "sudo apt install python3 -y", "echo Done!"] + + connection { + host = self.ipv4_address + type = "ssh" + user = "root" + private_key = file(var.pvt_key) + } + } +} + resource "local_file" "hosts_cfg" { - content = templatefile("${path.module}/templates/hosts.tpl", + content = templatefile("${path.module}/templates/hosts.tftpl", { - serverctl_masters = hcloud_server.serverctl_master.*.ipv4_address - serverctl_nodes = hcloud_server.serverctl_node.*.ipv4_address + serverctl_masters = hcloud_server.serverctl_master.*.ipv4_address + serverctl_nodes = hcloud_server.serverctl_node.*.ipv4_address + serverctl_mesh_nodes = hcloud_server.serverctl_mesh.*.ipv4_address } ) filename = "ansible/inventory/hosts.cfg" diff --git a/infrastructure/create-resources/templates/hosts.tftpl b/infrastructure/create-resources/templates/hosts.tftpl new file mode 100644 index 0000000..cfbe8ad --- /dev/null +++ b/infrastructure/create-resources/templates/hosts.tftpl @@ -0,0 +1,23 @@ +[serverctl_master_hosts] +%{ for ip in serverctl_masters ~} +${ip} +%{ endfor ~} + +[serverctl_node_hosts] +%{ for ip in serverctl_nodes ~} +${ip} +%{ endfor ~} + +[serverctl_mesh_nodes] +%{ for ip in serverctl_mesh_nodes ~} +${ip} ansible_host=${ip} wireguard_ip=${cidrhost("192.168.0.0/24", index(serverctl_mesh_nodes, ip) + 1)} +%{ endfor ~} + +[serverctl_mesh_nodes:vars] +pipelining=true +ansible_ssh_user=root +ansible_ssh_port=22 + +[serverctl_cluster:children] +serverctl_master_hosts +serverctl_node_hosts diff --git a/infrastructure/create-resources/templates/hosts.tpl b/infrastructure/create-resources/templates/hosts.tpl deleted file mode 100644 index 3d857e1..0000000 --- a/infrastructure/create-resources/templates/hosts.tpl +++ /dev/null @@ -1,13 +0,0 @@ -[serverctl_master_hosts] -%{ for ip in serverctl_masters ~} -${ip} -%{ endfor ~} - -[serverctl_node_hosts] -%{ for ip in serverctl_nodes ~} -${ip} -%{ endfor ~} - -[serverctl_cluster:children] -serverctl_master_hosts -serverctl_node_hosts