From 8072eb9434427efc547ab735a4c8dd9533b14cbc Mon Sep 17 00:00:00 2001 From: Oli Date: Sun, 9 Oct 2022 21:13:41 +0000 Subject: [PATCH] initial terraform code --- .gitignore | 37 ++++++++++++++++++ .terraform.lock.hcl | 46 ++++++++++++++++++++++ cloud.userdata | 19 +++++++++ dns.tf | 21 ++++++++++ firewall.tf | 32 ++++++++++++++++ instances.tf | 93 +++++++++++++++++++++++++++++++++++++++++++++ main.tf | 34 +++++++++++++++++ network.tf | 13 +++++++ volume.tf | 19 +++++++++ 9 files changed, 314 insertions(+) create mode 100644 .gitignore create mode 100644 .terraform.lock.hcl create mode 100644 cloud.userdata create mode 100644 dns.tf create mode 100644 firewall.tf create mode 100644 instances.tf create mode 100644 main.tf create mode 100644 network.tf create mode 100644 volume.tf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..48c784d --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# ---> Terraform +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log + +# Exclude all .tfvars files, which are likely to contain sentitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +# +*secret*.tfvars + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +*tfplan* + +# Ignore CLI configuration files +.terraformrc +terraform.rc + +tfplan_dl diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl new file mode 100644 index 0000000..b16a819 --- /dev/null +++ b/.terraform.lock.hcl @@ -0,0 +1,46 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hetznercloud/hcloud" { + version = "1.35.2" + constraints = "1.35.2" + hashes = [ + "h1:a/DH+2jHvgikSDajup5feRZRUwNw8OT9NBPKezjgM5g=", + "zh:1a7cb8f9cbd51b62bdbb4f36cdb070dd99059d86115c4777193e0f8536798d4d", + "zh:29c104aae7f7a4e1a4aea32febc9caa2d7d86589cd9d01d5b93dbe2cb0a73220", + "zh:29f082195d8f4e4cfb4050fae2ed62ed5616659c6dfaa7b5f1eb42d94d130864", + "zh:3cfe3876763659e27696adcb945e6da2dc2ec014ff8a2e8f0f3e610e3bfd9b73", + "zh:3d967f4b1aef78ffce389dd32cdea4b558ef826cec96ceb4bdafde4bb4a9b655", + "zh:3e160f581f7912c2053f86d6d8a3e3470fcf1fe8228b59ac216a7e40a1dd444c", + "zh:5138022c8b4c8a572e8097749241d929a96d3522e67ce25f86bb9fd51c4b343c", + "zh:5783febc4d8ac4b7fdb49607cab92ad13509d87ad4ca1999067ac3d20e815d12", + "zh:7f8ce9268d48beb5fa0103a8510d4fe644aaac6cd328fc4441dd37e8bdbfadab", + "zh:8ab6aea82657fd6f97d79b41e6cd129a33a47ce727a7d0b52205590fa3785ce1", + "zh:9e4bebe3bbee7875dc2e3ceca3cf0fec3254a8b481c7b96ba9a5d65647ea9092", + "zh:af2a912db9a6fce844ac8c0e695a5d92a5625f2df126129940051a6b1021443d", + "zh:bfe86d80e55f44a99dbbdca9d1caf0c837fe21d91e78674ee36263b7de71fd38", + "zh:d9538a361bd8979c4a87273a82fc5dec7110f3aa7ec69fffb8c70fe8937bc1f4", + ] +} + +provider "registry.terraform.io/ionos-developer/ionosdeveloper" { + version = "0.0.1" + constraints = ">= 0.0.1" + hashes = [ + "h1:EsbYrlAajO0JuWTtDmY5srsWm8TWOEtM+VfliBgSmag=", + "zh:04dc3d964dac33d1ff16e5893517c8b724cc0726bb93cb7bcd95eca25bb028fa", + "zh:090e552495d6766b26380a49c2bea4fdd898f0de641792b646bfc9e844ae5ab7", + "zh:0fe5eb23d65c42792d51ea55dce1f00ef1dd0ecba710827efd9218369dba6463", + "zh:1f71e1db13d3d6dfc09d6e95f8232ce23c78c72d126db23499f22c529496a744", + "zh:557325b7766cbc4ccbc0fee36469ecc0c96fb3bc7cf75036289161444906cb63", + "zh:7cbb553d04fa5cb53fd13e3684709712fde9ef5be0dca8e2eca8d27c8cda6bb1", + "zh:9fed4131682204eb4e1a4d05000192a904d3645305c52d05d8fac5e3f264a1f6", + "zh:b1cfb981617a3b276fbd95d60831e6f8a3207e806acb0dfa48f3d880694ecfe7", + "zh:b32a84063690cf3cf7c72b63051dc51d3da9697d355f100bb51ef4c766e14b04", + "zh:b3eea4f8cbd8a452f0688f0839009387ade879be768ea378dfc61937657cea00", + "zh:b865969d0ad218f96716c96128545afe11974717ec48a8dfb4b22f21c439c25e", + "zh:d1c06c76da4ad5f3589b0361fcb8cf563d651fe6e7261828d2d8e36a9b1bc727", + "zh:e60a2ad003970d038ac9bae82a7983315e186e22d51b78c52301a4fa7ccd3655", + "zh:f0544e6b18b2af7b0d2a567d33f304df9a9961a94f2692c7af91aef4f2b785df", + ] +} diff --git a/cloud.userdata b/cloud.userdata new file mode 100644 index 0000000..c7e74dd --- /dev/null +++ b/cloud.userdata @@ -0,0 +1,19 @@ +#cloud-config +users: + - name: oli + primary_group: oli + groups: sudo + shell: /bin/bash + sudo: ALL=(ALL) NOPASSWD:ALL + ssh_authorized_keys: + - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFpczZfQ5MrfjSYz8MnDHG4sM2cQ8cIsj3ALDGtmW3zu + +package_update: true +package_upgrade: true + +runcmd: + - sed -i -e '/^PermitRootLogin/s/^.*$/PermitRootLogin no/' /etc/ssh/sshd_config + - sed -i -e '/^PasswordAuthentication/s/^.*$/PasswordAuthentication no/' /etc/ssh/sshd_config + - sed -i -e '/^X11Forwarding/s/^.*$/X11Forwarding no/' /etc/ssh/sshd_config + - sed -i -e '/^#MaxAuthTries/s/^.*$/MaxAuthTries 3/' /etc/ssh/sshd_config + - systemctl restart sshd.service diff --git a/dns.tf b/dns.tf new file mode 100644 index 0000000..384e1c4 --- /dev/null +++ b/dns.tf @@ -0,0 +1,21 @@ +# IONOS DNS + +data "ionosdeveloper_dns_zone" "selected" { + name = "twirling.de" +} + +resource "ionosdeveloper_dns_record" "main_ipv4" { + zone_id = data.ionosdeveloper_dns_zone.selected.id + name = "cloud.${data.ionosdeveloper_dns_zone.selected.name}" + type = "A" + content = hcloud_primary_ip.main_ipv4.ip_address + ttl = 3600 +} + +resource "ionosdeveloper_dns_record" "main_ipv6" { + zone_id = data.ionosdeveloper_dns_zone.selected.id + name = "cloud.${data.ionosdeveloper_dns_zone.selected.name}" + type = "AAAA" + content = hcloud_primary_ip.main_ipv6.ip_address + ttl = 3600 +} \ No newline at end of file diff --git a/firewall.tf b/firewall.tf new file mode 100644 index 0000000..5e8d56d --- /dev/null +++ b/firewall.tf @@ -0,0 +1,32 @@ +# Hetzner Cloud Firewall + +resource "hcloud_firewall" "icmp" { + name = "ICMP" + rule { + direction = "in" + protocol = "icmp" + source_ips = [ + "0.0.0.0/0", + "::/0" + ] + } + apply_to { + label_selector = "env=prod" + } +} + +resource "hcloud_firewall" "ssh" { + name = "SSH" + rule { + direction = "in" + protocol = "tcp" + port = "22" + source_ips = [ + var.ows_gateway.ipv4, + var.ows_gateway.ipv6 + ] + } + apply_to { + label_selector = "env=prod" + } +} diff --git a/instances.tf b/instances.tf new file mode 100644 index 0000000..5b9ccbc --- /dev/null +++ b/instances.tf @@ -0,0 +1,93 @@ +# Create a new SSH key in cloud console +resource "hcloud_ssh_key" "default" { + name = "terraform-ansible" + public_key = var.dtsv_hcloud_ssh_key +} + +# Hetzner Primary IP + +resource "hcloud_primary_ip" "main_ipv4" { + name = "primary_ipv4_web" + datacenter = "fsn1-dc14" + type = "ipv4" + assignee_type = "server" + auto_delete = false + labels = { + "mapping" : "WEB" + } +} + +resource "hcloud_primary_ip" "main_ipv6" { + name = "primary_ipv6_web" + datacenter = "fsn1-dc14" + type = "ipv6" + assignee_type = "server" + auto_delete = false + labels = { + "mapping" : "WEB" + } +} + +# Hetzner Cloud Servers + +resource "hcloud_server" "web" { + name = "WEB" + server_type = "cpx21" + image = "ubuntu-22.04" + datacenter = "fsn1-dc14" + ssh_keys = [hcloud_ssh_key.default.id] + user_data = file("cloud.userdata") + labels = { + "env" : "prod" + } + + network { + network_id = hcloud_network.vpc.id + ip = "10.0.0.2" + } + + public_net { + ipv4_enabled = true + ipv4 = hcloud_primary_ip.main_ipv4.id + ipv6_enabled = true + ipv6 = hcloud_primary_ip.main_ipv6.id + } + + # **Note**: the depends_on is important when directly attaching the + # server to a network. Otherwise Terraform will attempt to create + # server and sub-network in parallel. This may result in the server + # creation failing randomly. + depends_on = [ + hcloud_network_subnet.subnet + ] +} + +resource "hcloud_server" "db" { + name = "DB" + server_type = "cpx11" + image = "ubuntu-22.04" + datacenter = "fsn1-dc14" + ssh_keys = [hcloud_ssh_key.default.id] + user_data = file("cloud.userdata") + labels = { + "env" : "prod" + } + + network { + network_id = hcloud_network.vpc.id + ip = "10.0.0.3" + } + + public_net { + ipv4_enabled = true + ipv6_enabled = true + } + + # **Note**: the depends_on is important when directly attaching the + # server to a network. Otherwise Terraform will attempt to create + # server and sub-network in parallel. This may result in the server + # creation failing randomly. + depends_on = [ + hcloud_network_subnet.subnet + ] +} \ No newline at end of file diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..51e66c5 --- /dev/null +++ b/main.tf @@ -0,0 +1,34 @@ +# Providers +terraform { + required_providers { + hcloud = { + source = "hetznercloud/hcloud" + version = "1.35.2" + } + ionosdeveloper = { + source = "ionos-developer/ionosdeveloper" + version = ">= 0.0.1" + } + } +} + +# Set the variable value in *.tfvars file +# or using the -var="hcloud_token=..." CLI option +# or get from env variable (export = abc132) + +# Hetzner Cloud +variable "dtsv_hcloud_token" {} +# Configure the Hetzner Cloud Provider +provider "hcloud" { + token = var.dtsv_hcloud_token +} + +# Ionos Cloud +variable "dtsv_ionos_token" {} +# Configure the Ionos Developer Provider +provider "ionosdeveloper" { + api_key = var.dtsv_ionos_token +} + +# Public SSH Key +variable "dtsv_hcloud_ssh_key" {} diff --git a/network.tf b/network.tf new file mode 100644 index 0000000..321b2c4 --- /dev/null +++ b/network.tf @@ -0,0 +1,13 @@ +# Hetzner Cloud Networks + +resource "hcloud_network" "vpc" { + name = "VPC" + ip_range = "10.0.0.0/24" +} + +resource "hcloud_network_subnet" "subnet" { + type = "cloud" + network_id = hcloud_network.vpc.id + network_zone = "eu-central" + ip_range = "10.0.0.0/24" +} \ No newline at end of file diff --git a/volume.tf b/volume.tf new file mode 100644 index 0000000..44232b5 --- /dev/null +++ b/volume.tf @@ -0,0 +1,19 @@ +# Hetzner Cloud Volume + +resource "hcloud_volume" "web" { + name = "WEB" + location = "fsn1" + size = 10 + format = "ext4" + delete_protection = true + labels = { + "env" : "prod" + "attachment" : "WEB" + } +} + +resource "hcloud_volume_attachment" "volume_attachment_web" { + volume_id = hcloud_volume.web.id + server_id = hcloud_server.web.id + automount = false +} \ No newline at end of file