Add healthchecksio provider and refactor ip-for-host collection
This commit is contained in:
		
							parent
							
								
									ed51a86935
								
							
						
					
					
						commit
						6fdfd338a1
					
				
					 14 changed files with 147 additions and 49 deletions
				
			
		
							
								
								
									
										18
									
								
								.terraform.lock.hcl
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										18
									
								
								.terraform.lock.hcl
									
										
									
										generated
									
									
									
								
							|  | @ -136,6 +136,24 @@ provider "registry.opentofu.org/hetznercloud/hcloud" { | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | provider "registry.opentofu.org/kristofferahl/healthchecksio" { | ||||||
|  |   version     = "1.6.3" | ||||||
|  |   constraints = "~> 1.6.0" | ||||||
|  |   hashes = [ | ||||||
|  |     "h1:UG8BANZc208Tjw/Byraf+1W7waDCusGmolAxeiGZ9eQ=", | ||||||
|  |     "zh:12cd30c19472bcecbd81f9fb6555f055d8a665477a1b2aadd20a9d43b95df0cf", | ||||||
|  |     "zh:174bbe2e2f49132fb4fb9c2b5abaa5743ba49c29f970daae32b7774c8eb259fd", | ||||||
|  |     "zh:214c06082f93bbd11919f73e5bdded8f916c990a2c2c46103c827e070120a6ea", | ||||||
|  |     "zh:21db5fa48fc61cd88e72d34414063e15d99677d871bdb4d231800c8f7daf6bc1", | ||||||
|  |     "zh:39b8d77b8849b3bdd0167ecd465d1980dd42bc1f3cbb9136c9cf8281d36d446a", | ||||||
|  |     "zh:5b81782d766a41272767b6804520eb8d07e82986f5d90818b3f000b26e4efdf2", | ||||||
|  |     "zh:8c045b836f4e6d86518f12c4b113db43715bad412f7f3cde7afbcc87a21bbfe1", | ||||||
|  |     "zh:9c3c6cedd21298d78c93c8a76d8a144a519664bd9def34c5b4a830f2aeeabe6d", | ||||||
|  |     "zh:9f1e6a1aba1d21b90c6bf4520c4b5b5d2fce20bd988852a6429acbc6365fa151", | ||||||
|  |     "zh:a5d15ed31ac4bc194bc7a32e96e902d7b322ab032c1637c67b16dbee968d1fae", | ||||||
|  |   ] | ||||||
|  | } | ||||||
|  | 
 | ||||||
| provider "registry.opentofu.org/ovh/ovh" { | provider "registry.opentofu.org/ovh/ovh" { | ||||||
|   version     = "0.48.0" |   version     = "0.48.0" | ||||||
|   constraints = "~> 0.48.0" |   constraints = "~> 0.48.0" | ||||||
|  |  | ||||||
							
								
								
									
										7
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										7
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -22,12 +22,17 @@ PWD := $(shell pwd) | ||||||
| 		| yq -y '{opentofu: with_entries(.value |= .value)}' \
 | 		| yq -y '{opentofu: with_entries(.value |= .value)}' \
 | ||||||
| 		> ./inventory/group_vars/all/opentofu.yaml | 		> ./inventory/group_vars/all/opentofu.yaml | ||||||
| 
 | 
 | ||||||
| outputs: ./dns/hosts.json ./dns/services.json ./inventory/group_vars/all/opentofu.yaml | output: ./dns/hosts.json ./dns/services.json ./inventory/group_vars/all/opentofu.yaml | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| ./types-dnscontrol.d.ts: | ./types-dnscontrol.d.ts: | ||||||
| 	dnscontrol write-types | 	dnscontrol write-types | ||||||
| 
 | 
 | ||||||
|  | tofu: | ||||||
|  | 	tofu apply | ||||||
|  | 	echo "\n=====\n" | ||||||
|  | 	$(MAKE) output | ||||||
|  | 
 | ||||||
| dns: ./types-dnscontrol.d.ts ./dns/hosts.json ./dns/services.json | dns: ./types-dnscontrol.d.ts ./dns/hosts.json ./dns/services.json | ||||||
| 	dnscontrol push | 	dnscontrol push | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -8,38 +8,28 @@ all: | ||||||
|     local-dev: |     local-dev: | ||||||
|       ansible_connection: local |       ansible_connection: local | ||||||
| 
 | 
 | ||||||
|     node001: |  | ||||||
|       ansible_host: node001.vpn.serguzim.net |  | ||||||
|       ansible_port: "{{ vault_node001.ansible_port }}" |  | ||||||
|       ansible_user: "{{ vault_node001.ansible_user }}" |  | ||||||
|       interactive_user: "{{ vault_node001.interactive_user }}" |  | ||||||
|       host_vpn: |  | ||||||
|         domain: node001.vpn.serguzim.net |  | ||||||
|         ip: 100.64.0.1 |  | ||||||
|       host_backup: |  | ||||||
|         hc_uid: "{{ vault_node001.backup.hc_uid }}" |  | ||||||
|         uptime_kuma_token: "{{ vault_node001.backup.uptime_kuma_token }}" |  | ||||||
| 
 |  | ||||||
|     node002: |     node002: | ||||||
|       ansible_host: node002.vpn.serguzim.net |       ansible_host: "{{ opentofu.hosts.node002.fqdn_vpn }}" | ||||||
|       ansible_port: "{{ vault_node002.ansible_port }}" |       ansible_port: "{{ vault_node002.ansible_port }}" | ||||||
|       ansible_user: "{{ vault_node002.ansible_user }}" |       ansible_user: "{{ vault_node002.ansible_user }}" | ||||||
|       interactive_user: "{{ vault_node002.interactive_user }}" |       interactive_user: "{{ vault_node002.interactive_user }}" | ||||||
|       host_vpn: |       host_vpn: | ||||||
|         domain: node002.vpn.serguzim.net |         domain: "{{ opentofu.hosts.node002.fqdn_vpn }}" | ||||||
|         ip: 100.64.0.2 |         ip: "{{ opentofu.hosts.node002.ipv4_address_vpn }}" | ||||||
|       host_backup: |       host_backup: | ||||||
|         hc_uid: "{{ vault_node002.backup.hc_uid }}" |         hc_uid: "{{ opentofu.healthchecksio.backup.node002.id }}" | ||||||
|  |         hc_url: "{{ opentofu.healthchecksio.backup.node002.ping_url }}" | ||||||
|         uptime_kuma_token: "{{ vault_node002.backup.uptime_kuma_token }}" |         uptime_kuma_token: "{{ vault_node002.backup.uptime_kuma_token }}" | ||||||
| 
 | 
 | ||||||
|     node003: |     node003: | ||||||
|       ansible_host: node003.vpn.serguzim.net |       ansible_host: "{{ opentofu.hosts.node003.fqdn_vpn }}" | ||||||
|       ansible_port: "{{ vault_node003.ansible_port }}" |       ansible_port: "{{ vault_node003.ansible_port }}" | ||||||
|       ansible_user: "{{ vault_node003.ansible_user }}" |       ansible_user: "{{ vault_node003.ansible_user }}" | ||||||
|       interactive_user: "{{ vault_node003.interactive_user }}" |       interactive_user: "{{ vault_node003.interactive_user }}" | ||||||
|       host_vpn: |       host_vpn: | ||||||
|         domain: node003.vpn.serguzim.net |         domain: "{{ opentofu.hosts.node003.fqdn_vpn }}" | ||||||
|         ip: 100.110.16.30 |         ip: "{{ opentofu.hosts.node003.ipv4_address_vpn }}" | ||||||
|       host_backup: |       host_backup: | ||||||
|         hc_uid: "{{ vault_node003.backup.hc_uid }}" |         hc_uid: "{{ opentofu.healthchecksio.backup.node003.id }}" | ||||||
|  |         hc_url: "{{ opentofu.healthchecksio.backup.node003.ping_url }}" | ||||||
|         uptime_kuma_token: "{{ vault_node003.backup.uptime_kuma_token }}" |         uptime_kuma_token: "{{ vault_node003.backup.uptime_kuma_token }}" | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								main.tf
									
										
									
									
									
								
							
							
						
						
									
										2
									
								
								main.tf
									
										
									
									
									
								
							|  | @ -42,6 +42,8 @@ module "infrastructure" { | ||||||
| 
 | 
 | ||||||
|   hcloud_token = var.hcloud_token |   hcloud_token = var.hcloud_token | ||||||
| 
 | 
 | ||||||
|  |   healthchecksio_api_key = var.healthchecksio_api_key | ||||||
|  | 
 | ||||||
|   ovh_application_key = var.ovh_application_key |   ovh_application_key = var.ovh_application_key | ||||||
|   ovh_application_secret = var.ovh_application_secret |   ovh_application_secret = var.ovh_application_secret | ||||||
|   ovh_consumer_key = var.ovh_consumer_key |   ovh_consumer_key = var.ovh_consumer_key | ||||||
|  |  | ||||||
							
								
								
									
										32
									
								
								modules/infrastructure/healthchecksio.tf
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								modules/infrastructure/healthchecksio.tf
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,32 @@ | ||||||
|  | data "healthchecksio_channel" "email" { | ||||||
|  |   kind = "email" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | data "healthchecksio_channel" "signal" { | ||||||
|  |   kind = "signal" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | data "healthchecksio_channel" "ntfy" { | ||||||
|  |   kind = "ntfy" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | resource "healthchecksio_check" "backup" { | ||||||
|  |   for_each = var.hosts | ||||||
|  | 
 | ||||||
|  |   name = "backup@${each.value.hostname}" | ||||||
|  |   desc = "A check for the backup on ${each.value.hostname}" | ||||||
|  | 
 | ||||||
|  |   tags = [ | ||||||
|  |     "backup", | ||||||
|  |     each.value.hostname, | ||||||
|  |   ] | ||||||
|  | 
 | ||||||
|  |   channels = [ | ||||||
|  |     data.healthchecksio_channel.email.id, | ||||||
|  |     data.healthchecksio_channel.signal.id, | ||||||
|  |     data.healthchecksio_channel.ntfy.id, | ||||||
|  |   ] | ||||||
|  | 
 | ||||||
|  |   timeout = 86400 | ||||||
|  |   grace = 1800 | ||||||
|  | } | ||||||
|  | @ -8,6 +8,10 @@ terraform { | ||||||
|       source = "hetznercloud/hcloud" |       source = "hetznercloud/hcloud" | ||||||
|       version = "~> 1.45.0" |       version = "~> 1.45.0" | ||||||
|     } |     } | ||||||
|  |     healthchecksio = { | ||||||
|  |       source = "kristofferahl/healthchecksio" | ||||||
|  |       version = "~> 1.6.0" | ||||||
|  |     } | ||||||
|     ovh = { |     ovh = { | ||||||
|       source = "ovh/ovh" |       source = "ovh/ovh" | ||||||
|       version = "~> 0.48.0" |       version = "~> 0.48.0" | ||||||
|  | @ -34,6 +38,10 @@ provider "hcloud" { | ||||||
|   token = var.hcloud_token |   token = var.hcloud_token | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | provider "healthchecksio" { | ||||||
|  |   api_key = var.healthchecksio_api_key | ||||||
|  | } | ||||||
|  | 
 | ||||||
| provider "ovh" { | provider "ovh" { | ||||||
|   endpoint = "ovh-eu" |   endpoint = "ovh-eu" | ||||||
|   application_key = var.ovh_application_key |   application_key = var.ovh_application_key | ||||||
|  |  | ||||||
|  | @ -1,17 +1,38 @@ | ||||||
| output "hosts" { | output "hosts" { | ||||||
|   value = { |   value = { | ||||||
|     for subdomain in distinct([for record in ovh_domain_zone_record.server_records : record.subdomain]) :  |     for key, host in var.hosts : | ||||||
|     subdomain => { |     key => { | ||||||
|       "hostname" = subdomain |       "hostname" = host.hostname | ||||||
|       "fqdn" = "${subdomain}.${ovh_domain_zone_record.server_records["${subdomain}:ipv4"].zone}" |       "fqdn" = "${host.hostname}.serguzim.net" | ||||||
|  |       "fqdn_vpn" = "${host.hostname}.vpn.serguzim.net" | ||||||
|       "ipv4_address" = try( |       "ipv4_address" = try( | ||||||
|         ovh_domain_zone_record.server_records["${subdomain}:ipv4"].target,  |         local.server_addresses_separated["${key}:ipv4"].address, | ||||||
|         null |         null | ||||||
|       ) |       ) | ||||||
|       "ipv6_address" = try( |       "ipv6_address" = try( | ||||||
|         ovh_domain_zone_record.server_records["${subdomain}:ipv6"].target,  |         local.server_addresses_separated["${key}:ipv6"].address, | ||||||
|         null |         null | ||||||
|       ) |       ) | ||||||
|  | 
 | ||||||
|  |       ipv4_address_vpn = try( | ||||||
|  |         local.tailscale_host_addresses_separated["${key}:ipv4"].address, | ||||||
|  |         null | ||||||
|  |       ) | ||||||
|  |       ipv6_address_vpn = try( | ||||||
|  |         local.tailscale_host_addresses_separated["${key}:ipv6"].address, | ||||||
|  |         null | ||||||
|  |       ) | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | output "healthchecksio" { | ||||||
|  |   value = { | ||||||
|  |     backup = { | ||||||
|  |       for key, check in healthchecksio_check.backup : key => { | ||||||
|  |         "id" = check.id | ||||||
|  |         "ping_url" = check.ping_url | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,8 +1,9 @@ | ||||||
| locals { | locals { | ||||||
|   server_addresses = flatten([ |   server_addresses = flatten([ | ||||||
|     [ |     [ | ||||||
|       for host in contabo_instance.nodes : [ |       for key, host in contabo_instance.nodes : [ | ||||||
|         { |         { | ||||||
|  |           key = key | ||||||
|           hostname = host.display_name |           hostname = host.display_name | ||||||
|           ipv4_address = host.ip_config[0].v4[0].ip |           ipv4_address = host.ip_config[0].v4[0].ip | ||||||
|           ipv6_address = host.ip_config[0].v6[0].ip |           ipv6_address = host.ip_config[0].v6[0].ip | ||||||
|  | @ -10,8 +11,9 @@ locals { | ||||||
|       ] |       ] | ||||||
|     ], |     ], | ||||||
|     [ |     [ | ||||||
|       for host in hcloud_server.nodes : [ |       for key, host in hcloud_server.nodes : [ | ||||||
|         { |         { | ||||||
|  |           key = key | ||||||
|           hostname = host.name |           hostname = host.name | ||||||
|           ipv4_address = host.ipv4_address |           ipv4_address = host.ipv4_address | ||||||
|           ipv6_address = host.ipv6_address |           ipv6_address = host.ipv6_address | ||||||
|  | @ -20,34 +22,32 @@ locals { | ||||||
|     ] |     ] | ||||||
|   ]) |   ]) | ||||||
| 
 | 
 | ||||||
|   server_addresses_separated = flatten([ |   server_addresses_separated = merge([ | ||||||
|     for host in local.server_addresses : [ |     for host in local.server_addresses : { | ||||||
|       { |       "${host.key}:ipv4" = { | ||||||
|         hostname = host.hostname |         hostname = host.hostname | ||||||
|         key      = "${host.hostname}:ipv4" |  | ||||||
|         address  = host.ipv4_address |         address  = host.ipv4_address | ||||||
|       }, |       }, | ||||||
|       { |       "${host.key}:ipv6" = { | ||||||
|         hostname = host.hostname |         hostname = host.hostname | ||||||
|         key      = "${host.hostname}:ipv6" |  | ||||||
|         address  = host.ipv6_address |         address  = host.ipv6_address | ||||||
|       }, |       }, | ||||||
|     ] |     } | ||||||
|   ]) |   ]...) | ||||||
| 
 | 
 | ||||||
|   tailscale_host_addresses = flatten([ |   tailscale_host_addresses_separated = merge([ | ||||||
|     for host in data.tailscale_devices.nodes.devices : [ |     for host in data.tailscale_devices.nodes.devices : { | ||||||
|       for index, address in host.addresses : { |       for address in host.addresses : | ||||||
|         hostname = host.hostname |         "${host.hostname}:${strcontains(address, ":") ? "ipv6" : "ipv4"}" => { | ||||||
|         key      = "${host.hostname}:${index}" |           hostname = host.hostname | ||||||
|         address  = address |           address  = address | ||||||
|       } |         } | ||||||
|     ] |     } | ||||||
|   ]) |   ]...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| resource "ovh_domain_zone_record" "server_records" { | resource "ovh_domain_zone_record" "server_records" { | ||||||
|   for_each  = { for entry in local.server_addresses_separated: entry.key => entry } |   for_each  = local.server_addresses_separated | ||||||
|   zone      = "serguzim.net" |   zone      = "serguzim.net" | ||||||
|   subdomain = each.value.hostname |   subdomain = each.value.hostname | ||||||
|   fieldtype = strcontains(each.value.address, ":") ? "AAAA" : "A" |   fieldtype = strcontains(each.value.address, ":") ? "AAAA" : "A" | ||||||
|  | @ -56,7 +56,7 @@ resource "ovh_domain_zone_record" "server_records" { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| resource "ovh_domain_zone_record" "tailscale_vpn" { | resource "ovh_domain_zone_record" "tailscale_vpn" { | ||||||
|   for_each  = { for entry in local.tailscale_host_addresses: entry.key => entry } |   for_each  = local.tailscale_host_addresses_separated | ||||||
|   zone      = "serguzim.net" |   zone      = "serguzim.net" | ||||||
|   subdomain = "${each.value.hostname}.vpn" |   subdomain = "${each.value.hostname}.vpn" | ||||||
|   fieldtype = strcontains(each.value.address, ":") ? "AAAA" : "A" |   fieldtype = strcontains(each.value.address, ":") ? "AAAA" : "A" | ||||||
|  |  | ||||||
|  | @ -9,3 +9,9 @@ resource "tailscale_tailnet_key" "cloud_init_key" { | ||||||
| data "tailscale_devices" "nodes" { | data "tailscale_devices" "nodes" { | ||||||
|   name_prefix = "node" |   name_prefix = "node" | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | locals { | ||||||
|  |   tailscale_devices = { | ||||||
|  |     for host in data.tailscale_devices.nodes.devices : host.hostname => host | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | @ -20,6 +20,11 @@ variable "hcloud_token" { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | variable "healthchecksio_api_key" { | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| variable "ovh_application_key" { | variable "ovh_application_key" { | ||||||
|   sensitive = true |   sensitive = true | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -7,6 +7,10 @@ output "authentik_data" { | ||||||
|   sensitive = true |   sensitive = true | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | output "healthchecksio" { | ||||||
|  |   value = module.infrastructure.healthchecksio | ||||||
|  | } | ||||||
|  | 
 | ||||||
| output "postgresql_data" { | output "postgresql_data" { | ||||||
|   value = module.services.postgresql_data |   value = module.services.postgresql_data | ||||||
|   sensitive = true |   sensitive = true | ||||||
|  |  | ||||||
|  | @ -13,7 +13,7 @@ backup_msg_success: "Backup successful" | ||||||
| backup_curl_base: 'curl -L -m 10 --retry 5' | backup_curl_base: 'curl -L -m 10 --retry 5' | ||||||
| backup_hc_curl_base: '{{ backup_curl_base }} -X POST -H "Content-Type: text/plain"' | backup_hc_curl_base: '{{ backup_curl_base }} -X POST -H "Content-Type: text/plain"' | ||||||
| backup_uk_curl_base: '{{ backup_curl_base }}' | backup_uk_curl_base: '{{ backup_curl_base }}' | ||||||
| backup_hc_url: 'https://hc-ping.com/{{ host_backup.hc_uid }}' | backup_hc_url: '{{ host_backup.hc_url }}' | ||||||
| backup_uk_url: 'https://status.serguzim.me/api/push/{{ host_backup.uptime_kuma_token }}' | backup_uk_url: 'https://status.serguzim.me/api/push/{{ host_backup.uptime_kuma_token }}' | ||||||
| 
 | 
 | ||||||
| backup_hc_command_start: '{{ backup_hc_curl_base }} --data "{{ backup_msg_start }}" {{ backup_hc_url }}/start' | backup_hc_command_start: '{{ backup_hc_curl_base }} --data "{{ backup_msg_start }}" {{ backup_hc_url }}/start' | ||||||
|  |  | ||||||
|  | @ -14,6 +14,8 @@ contabo_pass = "" | ||||||
| 
 | 
 | ||||||
| hcloud_token = "" | hcloud_token = "" | ||||||
| 
 | 
 | ||||||
|  | healthchecksio_api_key = "" | ||||||
|  | 
 | ||||||
| ovh_application_key = "" | ovh_application_key = "" | ||||||
| ovh_application_secret = "" | ovh_application_secret = "" | ||||||
| ovh_consumer_key = "" | ovh_consumer_key = "" | ||||||
|  |  | ||||||
|  | @ -50,6 +50,11 @@ variable "hcloud_token" { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | variable "healthchecksio_api_key" { | ||||||
|  |   sensitive = true | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| variable "ovh_application_key" { | variable "ovh_application_key" { | ||||||
|   sensitive = true |   sensitive = true | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue