Terraforming my blog
I’ve just pushed a first step for managing my infrastructure via Hashicorps Terraform. In this article I want to speak about this first step and I want to give a glimpse into the future for it.
My infrastructure is hosted in Hetzner Cloud (there is luckily a terraform provider for it). DNS will be talked about in a later blog article.
I usually store my passwords in a gopass password store, hence I’ve wanted to let Terraform retrieve the Hetzner Cloud API key magically.
The solution is the use of the external
Terraform module:
data "external" "hetzner_cloud_api_key" {
program = ["${path.module}/fetch-key.sh"]
}
This snippet will call a wrapper script called fetch-key.sh
, that basically
just calls gopass and translates the output to a JSON structure:
#!/bin/bash
hetzner_cloud_api_key=$(gopass api/hetzner.com/motoko)
echo "{ \"hetzner_cloud_api_key\": \"${hetzner_cloud_api_key}\" }"
It’s important to use the key hetzner_cloud_api_key
here! In the next part
I am going to set the hetzner_cloud_api_key
and call the hcloud
provider
(this is going to download a go binary):
provider "hcloud" {
token = data.external.hetzner_cloud_api_key.result.hetzner_cloud_api_key
}
Then we are setting the actual server resource and an rdns entry for the server:
resource "hcloud_server" "kurisu" {
name = "kurisu"
server_type = "cx11-ceph"
location = "fsn1"
image = "fedora-31"
lifecycle {
ignore_changes = [image]
}
}
resource "hcloud_rdns" "kurisu" {
server_id = hcloud_server.kurisu.id
ip_address = hcloud_server.kurisu.ipv4_address
dns_ptr = "kurisu.shibumi.dev"
}
Interesting is the last part of the hcloud_server
resource:
image = "fedora-31"
lifecycle {
ignore_changes = [image]
}
}
The image variable is actually never used. I have created my server with
Fedora-28 years ago. When Hetzner introduces a new Fedora image the last one
gets deprecated and the Hetzner Cloud API links that value against null
or
No Image
. Therefore any import of an existing server will fail, because you
can’t set the null
value to the image variable (it’s a requirement for the
hcloud_server
resource). And if you set any other string, the Hetzner Cloud
API will think it’s a valid image value and will try to destroy your image and
create a new one. To go around this issue, just add a lifecycle for it and set
ignore_changes = [image]
. This will ignore any changes to the image variable
on Hetzner Cloud API side.
If you want to have a look on all files go and checkout:
https://github.com/shibumi/infra
I will definitely work further on this. On my todo list are:
- DNS via inwx.de
- rDNS entries for IPv6
- Provisioning of the actual image (not sure if I will use Ansible or rely on this for Terraform too).