diff options
author | Jakob Odersky <jakob@odersky.com> | 2018-10-22 04:02:44 -0700 |
---|---|---|
committer | Jakob Odersky <jakob@odersky.com> | 2018-10-22 04:02:44 -0700 |
commit | 4d7a93c535ceeb720dc1873bfa61531099b611cb (patch) | |
tree | 5aa2c02bf756f72fecb5d7bf695a98edfdb417b2 /terraform | |
download | infra-4d7a93c535ceeb720dc1873bfa61531099b611cb.tar.gz infra-4d7a93c535ceeb720dc1873bfa61531099b611cb.tar.bz2 infra-4d7a93c535ceeb720dc1873bfa61531099b611cb.zip |
Initial commit
Diffstat (limited to 'terraform')
-rw-r--r-- | terraform/.gitignore | 22 | ||||
-rw-r--r-- | terraform/main.tf | 57 | ||||
-rw-r--r-- | terraform/role/README.md | 4 | ||||
-rw-r--r-- | terraform/role/main.tf | 91 | ||||
-rw-r--r-- | terraform/stdvps/README.md | 2 | ||||
-rw-r--r-- | terraform/stdvps/main.tf | 54 | ||||
-rwxr-xr-x | terraform/tf | 3 | ||||
-rw-r--r-- | terraform/volume/main.tf | 68 |
8 files changed, 301 insertions, 0 deletions
diff --git a/terraform/.gitignore b/terraform/.gitignore new file mode 100644 index 0000000..4aa60fc --- /dev/null +++ b/terraform/.gitignore @@ -0,0 +1,22 @@ +# Local .terraform directories +**/.terraform/* +terraform.d/ + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log + +# Ignore any .tfvars files that are generated automatically for each Terraform run. Most +# .tfvars files are managed as part of configuration and so should be included in +# version control. +# +# example.tfvars + +# Ignore override files as they are usually used to override ressources locally +override.tf +override.tf.json +*_override.tf +*_override.tf.json
\ No newline at end of file diff --git a/terraform/main.tf b/terraform/main.tf new file mode 100644 index 0000000..8a5e599 --- /dev/null +++ b/terraform/main.tf @@ -0,0 +1,57 @@ +variable "secret_hcloud_token" { + type = "string" +} + +variable "secret_cloudflare_token" { + type = "string" +} + +provider "hcloud" { + token = "${var.secret_hcloud_token}" +} + +provider "cloudflare" { + email = "jakob@odersky.com" + token = "${var.secret_cloudflare_token}" +} + +provider "acme" { + #server_url = "https://acme-staging-v02.api.letsencrypt.org/directory" + server_url = "https://acme-v02.api.letsencrypt.org/directory" +} + +################################################################################ + +# Main ssh key +resource "hcloud_ssh_key" "root" { + name = "root" + public_key = "${file("~/.ssh/id_rsa.pub")}" +} + +module "vps" { + source = "./stdvps" + location = "nbg1" + ssh_key_name = "${hcloud_ssh_key.root.name}" +} + +module "volume" { + source = "./volume" + server_id = "${module.vps.id}" + server_fqdn = "${module.vps.fqdn}" +} + +module "roles" { + source = "./role" + secret_cloudflare_token = "${var.secret_cloudflare_token}" + host = "${module.vps.fqdn}" + id = "${module.volume.server_id}" + roles = ["ip", "git"] +} + +output "vps_address" { + value = "${module.vps.fqdn}" +} + +output "vps_roles" { + value = "${join(" ", module.roles.roles)}" +} diff --git a/terraform/role/README.md b/terraform/role/README.md new file mode 100644 index 0000000..11e2e21 --- /dev/null +++ b/terraform/role/README.md @@ -0,0 +1,4 @@ +# Role-based configuration for standalone hosts. + +Applying a role to a host will install corresponding config packages +and create a role CNAME record to the host. diff --git a/terraform/role/main.tf b/terraform/role/main.tf new file mode 100644 index 0000000..e85fd3b --- /dev/null +++ b/terraform/role/main.tf @@ -0,0 +1,91 @@ +variable "host" { + type = "string" +} + +variable "id" { + type = "string" +} + +variable "roles" { + type = "list" +} + +variable "secret_cloudflare_token" { + type = "string" +} + +resource "tls_private_key" "private_key" { + algorithm = "RSA" +} + +resource "acme_registration" "reg" { + account_key_pem = "${tls_private_key.private_key.private_key_pem}" + email_address = "jakob@odersky.com" +} + +resource "acme_certificate" "certificate" { + account_key_pem = "${acme_registration.reg.account_key_pem}" + common_name = "${var.host}" + subject_alternative_names = "${formatlist("%s.crashbox.io", var.roles)}" + + dns_challenge { + provider = "cloudflare" + + config { + CLOUDFLARE_EMAIL = "jakob@odersky.com" + CLOUDFLARE_API_KEY = "${var.secret_cloudflare_token}" + } + } +} + +resource "cloudflare_record" "role_cname" { + count = "${length(var.roles)}" + + domain = "crashbox.io" + name = "${element(var.roles, count.index)}" + value = "${var.host}" + type = "CNAME" +} + +resource "null_resource" "role_config" { + triggers = { + host_id = "${var.id}" + config_packages = "${join(" ", sort(formatlist("crashbox-%s-config", var.roles)))}" + } + + connection { + host = "${var.host}" + } + + provisioner "file" { + content = "${acme_certificate.certificate.certificate_pem}" + destination = "/etc/ssl/server.cert.pem" + } + + provisioner "file" { + content = "${acme_certificate.certificate.issuer_pem}" + destination = "/etc/ssl/issuer.cert.pem" + } + + provisioner "file" { + content = "${acme_certificate.certificate.private_key_pem}" + destination = "/etc/ssl/private/server.key.pem" + } + + provisioner "file" { + source = "${path.root}/../packages/target/archive" + destination = "/usr/local/share/" + } + + provisioner "remote-exec" { + inline = [ + "echo deb [trusted=yes] file:/usr/local/share/archive ./ > /etc/apt/sources.list.d/local-archive.list", + "apt update --quiet=2", + "apt install --quiet=2 --yes ${null_resource.role_config.triggers.config_packages}", + ] + } +} + +output "roles" { + value = "${var.roles}" +} diff --git a/terraform/stdvps/README.md b/terraform/stdvps/README.md new file mode 100644 index 0000000..316641c --- /dev/null +++ b/terraform/stdvps/README.md @@ -0,0 +1,2 @@ +# stdvps +A basic cloud virtual machine. diff --git a/terraform/stdvps/main.tf b/terraform/stdvps/main.tf new file mode 100644 index 0000000..2328bb1 --- /dev/null +++ b/terraform/stdvps/main.tf @@ -0,0 +1,54 @@ +variable "ssh_key_name" { + type = "string" +} + +variable "location" { + type = "string" +} + +resource "random_id" "server" { + prefix = "peter-" + byte_length = 2 +} + +resource "hcloud_server" "server" { + name = "${random_id.server.hex}.crashbox.io" + image = "debian-9" + server_type = "cx11" + location = "${var.location}" + ssh_keys = ["${var.ssh_key_name}"] +} + +resource "cloudflare_record" "record_a" { + domain = "crashbox.io" + name = "${hcloud_server.server.name}" + value = "${hcloud_server.server.ipv4_address}" + type = "A" +} + +resource "cloudflare_record" "record_aaaa" { + domain = "crashbox.io" + name = "${hcloud_server.server.name}" + value = "${hcloud_server.server.ipv6_address}1" + type = "AAAA" +} + +output "ipv4" { + value = "${hcloud_server.server.ipv4_address}" +} + +output "ipv6" { + value = "${hcloud_server.server.ipv6_address}" +} + +output "fqdn" { + value = "${cloudflare_record.record_aaaa.hostname}" +} + +output "id" { + value = "${hcloud_server.server.id}" +} + +output "name" { + value = "${hcloud_server.server.name}" +} diff --git a/terraform/tf b/terraform/tf new file mode 100755 index 0000000..888e681 --- /dev/null +++ b/terraform/tf @@ -0,0 +1,3 @@ +#!/bin/bash + +exec terraform "$@" -var-file=<(pass infra/terraform)
\ No newline at end of file diff --git a/terraform/volume/main.tf b/terraform/volume/main.tf new file mode 100644 index 0000000..828d85d --- /dev/null +++ b/terraform/volume/main.tf @@ -0,0 +1,68 @@ +variable "server_fqdn" { + type = "string" +} + +variable "server_id" { + type = "string" +} + +resource "hcloud_volume" "master" { + name = "master" + size = 50 + server_id = "${var.server_id}" +} + +# this is only run once if the volume id changes +resource "null_resource" "volume_format" { + triggers = { + volume_id = "${hcloud_volume.master.id}" + } + + connection { + host = "${var.server_fqdn}" + } + + provisioner "remote-exec" { + inline = [ + "mkfs.ext4 ${hcloud_volume.master.linux_device}", + ] + } +} + +resource "null_resource" "volume_mount" { + triggers = { + server_id = "${var.server_id}" + volume_id = "${hcloud_volume.master.id}" + } + + connection { + host = "${var.server_fqdn}" + } + + provisioner "file" { + content = <<EOF +[Unit] +Description=Mount /srv directory + +[Mount] +What=${hcloud_volume.master.linux_device} +Where=/srv +Type=ext4 +Options=defaults +EOF + + destination = "/etc/systemd/system/srv.mount" + } + + provisioner "remote-exec" { + inline = [ + "systemctl daemon-reload", + "systemctl enable srv.mount", + "systemctl start srv.mount", + ] + } +} + +output "server_id" { + value = "${var.server_id}" +} |