From affc79addabce963a37f229f09ec2dc1dd0df8a3 Mon Sep 17 00:00:00 2001 From: mawalu Date: Sun, 22 Aug 2021 21:22:30 +0200 Subject: [PATCH] Initial commit --- .gitignore | 3 ++ config/config.libsonnet | 30 +++++++++++++++ credentials.libsonnet.template | 4 ++ lib/terraform.libsonnet | 35 +++++++++++++++++ services.jsonnet | 68 ++++++++++++++++++++++++++++++++++ 5 files changed, 140 insertions(+) create mode 100644 .gitignore create mode 100644 config/config.libsonnet create mode 100644 credentials.libsonnet.template create mode 100644 lib/terraform.libsonnet create mode 100644 services.jsonnet diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d13afd0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +credentials.libsonnet +.idea +out/* diff --git a/config/config.libsonnet b/config/config.libsonnet new file mode 100644 index 0000000..4f8c39b --- /dev/null +++ b/config/config.libsonnet @@ -0,0 +1,30 @@ +local credentials = import "../credentials.libsonnet"; +local terraform = import "../lib/terraform.libsonnet"; + +credentials + { + local hashIp(name) = std.substr(std.md5(name), 0, 4) + ":" + std.substr(std.md5(name), 4, 4), + + local serverMeta(name, instance) = { + name: name, + publicSubdomain: name + ".infra", + internalSubdomain: name + ".i.infra", + publicDomain: self.publicSubdomain + "." + $.infraDomain, + internalDomain: self.internalSubdomain + $.infraDomain, + wireguardIp: $.ipSubnet + ":" + hashIp(name), + instance: instance + { name: name } + }, + + infraDomain: "m5w.de", + # needs to be /96 + ipSubnet: "fdc2:d459:3f8a:84a3:coffe:coffe", + defaultTTL: 3600, + defaultZoneTTL: 86400, + sshKeys: { + martin: 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCzXsN8jgzF51mQS5gfo4H7QKNhDKDEyXZSGen83MYw9GyIMi+AdH1fuhnYBlN2fTlHjs88otZkBMhVzE5lbkutz07j+ZpF6AdUvxqesqkXa2hdXFBRRwnG7u0Pxbi7vhr7uUWMa1WzJYynwmYBLL0yNEK6dI1qJcpwaK6v8UOZymiSJh04Sqd1LfEKd7R3BdzRCqkeKab1351OmJSswN+HRsAsDbdOIDBXpUMomvYAxJud4Wv90NcXfYikI7lhaAILBPTSUQqgTFFHhjfw9pe6Uhxb5URVS5ENjYVDyD2Lo1daZwy+sSYvA1LKZLQVEBKyx1o6SLLsuYqOuOIxiy8UEQ9vLHBdYQ+Ca0m2TruPtxEIu67WQFMBjMXcja4p516UkiuFqr0sQftI0HvVIZHS95DTK2BygkOy9Aok/fQ4IBeraN9EjIRkAB5Hn0z8vxBQMf9ZKUisMbN8nk22YpGte1RD9BFS9Swm7IE1c55QD30S6tD5z0lMUcU+ol3rOIh/013hNj9ZLsYxOtGJtIX3Xc+tIbUgXKou1sjPGQx4M2t9RRZTJ8L4l2DYw4joNoFXGiwFW586DBMw6wb9YeikA+Nuy0RFY8ytgBD5Qdh7IbF7+aA8f0ZkGHkmf/VLM1UkO5XXh3bNlz03IPcav091mAAlu/OHCdOhN54V9vE1FQ== cardno:4268913' + }, + servers: [ + serverMeta("dust2", terraform.HcloudInstance { + server_type: "cx11" + }) + ] +} diff --git a/credentials.libsonnet.template b/credentials.libsonnet.template new file mode 100644 index 0000000..c202df4 --- /dev/null +++ b/credentials.libsonnet.template @@ -0,0 +1,4 @@ +{ + hcloudToken: "", + hdnsToken: "" +} diff --git a/lib/terraform.libsonnet b/lib/terraform.libsonnet new file mode 100644 index 0000000..1d51d61 --- /dev/null +++ b/lib/terraform.libsonnet @@ -0,0 +1,35 @@ +local config = import "../config/config.libsonnet"; + +{ + local terraform = self, + local rname (server, suffix) = "host_" + server.name + "_" + suffix, + + HcloudInstance:: { + name: error "Instance must have field: name", + image: "debian-11", + server_type: error "Instance must have field: server_type", + location: "fsn1" + }, + + HcloudSSHKey:: { + name: error "Key must have field: name", + public_key: error "Key must have field: public_key", + labels: { source: "terraform" } + }, + + HdnsRecord:: { + zone_id: "${hetznerdns_zone.infra.id}", + name: error "Record must have field: name", + value: error "Record must have field: value", + type: error "Record must have field: type", + ttl: config.defaultTTL + }, + + serverDnsRecords: function (s) { + local attr (s, n) = "${hcloud_server." + s.name + "." + n + "}", + + [rname(s, "A")]: terraform.HdnsRecord{ name: s.publicSubdomain, value: attr(s, "ipv4_address"), type: "A" }, + [rname(s, "AAAA")]: terraform.HdnsRecord{ name: s.publicSubdomain, value: attr(s, "ipv6_address"), type: "AAAA" }, + [rname(s, "VPN")]: terraform.HdnsRecord{ name: s.internalSubdomain, value: s.wireguardIp, type: "AAAA" }, + } +} diff --git a/services.jsonnet b/services.jsonnet new file mode 100644 index 0000000..d3f20c0 --- /dev/null +++ b/services.jsonnet @@ -0,0 +1,68 @@ +local terraform = import "lib/terraform.libsonnet"; +local config = import "config/config.libsonnet"; + +{ + "terraform.tf.json": std.manifestJson({ + terraform: { + required_providers: { + hcloud: { + source: "hetznercloud/hcloud", + version: "1.30.0" + }, + hetznerdns: { + source: "timohirt/hetznerdns", + version: "1.1.1" + } + } + }, + + provider: { + hcloud: { + token: config.hcloudToken + }, + hetznerdns: { + apitoken: config.hdnsToken + } + }, + + resource: { + hcloud_ssh_key: { + [k]: terraform.HcloudSSHKey { name: k, public_key: config.sshKeys[k] } + for k in std.objectFields(config.sshKeys) + }, + hcloud_server: { + [s.name]: s.instance + for s in config.servers + }, + hetznerdns_zone: { + infra: { name: config.infraDomain, ttl: config.defaultZoneTTL }, + }, + hetznerdns_record: std.foldl(function (a, b) a + b, [ + terraform.serverDnsRecords(s) + for s in config.servers + ], {}) + } + }), + "inventory.yaml": std.manifestYamlDoc({ + all: { + hosts: { + [s.name]: s + { + ansible_host: s.publicDomain, + ansible_user: "root" + } + for s in config.servers + } + } + }), + "site.yaml": std.manifestYamlDoc([ + { + name: "Test command", + hosts: "all", + tasks: [ + { + "ansible.builtin.command": "ls" + } + ] + } + ]) +}