Deploy VM's with Terraform in 10min
Page content
Managing VM’s on Hetzner Cloud with Terraform
you may want to manage some vm in the cloud. webgui is nice, but a real nerd needs cli ;)
some notes how to get terraform running with OpenBSD.
add Packages (3min)
$ time doas pkg_add git gmake go terraform
3m18.62s real 0m19.53s user 0m07.73s system
set GO PATH
echo "GOPATH=$HOME/go" >> ~/.profile
echo "export GOPATH" >> ~/.profile
. ./.profile
echo $GOPATH
build terraform provider for hcloud (2min)
As the hcloud is not available for OpenBSD, we have to build it on our own.
$ echo $GOPATH
/home/stoege/go
mkdir -p $GOPATH/src/github.com/hetznercloud
cd $GOPATH/src/github.com/hetznercloud
git clone https://github.com/hetznercloud/terraform-provider-hcloud.git
cd terraform-provider-hcloud
time gmake build
1m19.51s real 0m52.93s user 0m20.08s system
Install Provider (2min)
cd ~
ll /home/stoege/go/bin/
mkdir -p .terraform.d/plugins/registry.terraform.io/hetznercloud/hcloud/1.25.1/openbsd_amd64/
cp go/bin/terraform-provider-hcloud .terraform.d/plugins/registry.terraform.io/hetznercloud/hcloud/1.25.1/openbsd_amd64/
Terraform main.tf
Here, we build two VM’s based on existing snapshots. Learn how to Bootstrap OpenBSD
-> replace “YOUR_TOKEN_YOU_HAVE_CREATED_ON_HETZNER_CLOUD” with your own token ;)
cd ~
mkdir hetzner
cd hetzner
cat << 'EOF' > main.tf
############## Variables ###############
# Token variable
variable "hcloud_token" {
default = "YOUR_TOKEN_YOU_HAVE_CREATED_ON_HETZNER_CLOUD"
}
# Define Hetzner provider
provider "hcloud" {
token = var.hcloud_token
}
# Create an OpenBSD Server
resource "hcloud_server" "obsd" {
name = "obsd"
image = "33661841"
server_type = "cx11"
location = "nbg1"
}
# Create an FreeBSD Server
resource "hcloud_server" "fbsd" {
name = "fbsd"
image = "33811022"
server_type = "cx11"
location = "nbg1"
}
# Output server IPs
output "server_ip_obsd" {
value = hcloud_server.obsd.ipv4_address
}
output "server_ip_fbsd" {
value = hcloud_server.fbsd.ipv4_address
}
EOF
versions.tf
TF 13.0 and higher requires a version file
cat << 'EOF' > versions.tf
terraform {
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
}
}
required_version = ">= 0.13"
}
EOF
terraform init
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding latest version of hashicorp/hcloud...
Error: Failed to install providers
Could not find required providers, but found possible alternatives:
hashicorp/hcloud -> hetznercloud/hcloud
If these suggestions look correct, upgrade your configuration with the
following command:
terraform 0.13upgrade .
terraform upgrade
$ terraform 0.13upgrade .
This command will update the configuration files in the given directory to use
the new provider source features from Terraform v0.13. It will also highlight
any providers for which the source cannot be detected, and advise how to
proceed.
Would you like to upgrade the module in the current directory?
Only 'yes' will be accepted to confirm.
Enter a value: yes
-----------------------------------------------------------------------------
Upgrade complete!
terraform init
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Using previously-installed hetznercloud/hcloud v1.25.1
The following providers do not have any version constraints in configuration,
so the latest version was installed.
* hetznercloud/hcloud: version = "~> 1.25.1"
Terraform has been successfully initialized!
Problems ?
SOLVED hcloud provider is missing from the terraform registry
terraform plan
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# hcloud_server.fbsd will be created
+ resource "hcloud_server" "fbsd" {
+ backup_window = (known after apply)
+ backups = false
+ datacenter = (known after apply)
+ id = (known after apply)
+ image = "33811022"
+ ipv4_address = (known after apply)
+ ipv6_address = (known after apply)
+ ipv6_network = (known after apply)
+ keep_disk = false
+ location = "nbg1"
+ name = "fbsd"
+ server_type = "cx11"
+ status = (known after apply)
}
# hcloud_server.obsd will be created
+ resource "hcloud_server" "obsd" {
+ backup_window = (known after apply)
+ backups = false
+ datacenter = (known after apply)
+ id = (known after apply)
+ image = "33661841"
+ ipv4_address = (known after apply)
+ ipv6_address = (known after apply)
+ ipv6_network = (known after apply)
+ keep_disk = false
+ location = "nbg1"
+ name = "obsd"
+ server_type = "cx11"
+ status = (known after apply)
}
Plan: 2 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
terraform apply (1min)
$ terraform apply
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# hcloud_server.fbsd will be created
+ resource "hcloud_server" "fbsd" {
+ backup_window = (known after apply)
+ backups = false
+ datacenter = (known after apply)
+ id = (known after apply)
+ image = "33811022"
+ ipv4_address = (known after apply)
+ ipv6_address = (known after apply)
+ ipv6_network = (known after apply)
+ keep_disk = false
+ location = "nbg1"
+ name = "fbsd"
+ server_type = "cx11"
+ status = (known after apply)
}
# hcloud_server.obsd will be created
+ resource "hcloud_server" "obsd" {
+ backup_window = (known after apply)
+ backups = false
+ datacenter = (known after apply)
+ id = (known after apply)
+ image = "33661841"
+ ipv4_address = (known after apply)
+ ipv6_address = (known after apply)
+ ipv6_network = (known after apply)
+ keep_disk = false
+ location = "nbg1"
+ name = "obsd"
+ server_type = "cx11"
+ status = (known after apply)
}
Plan: 2 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
hcloud_server.fbsd: Creating...
hcloud_server.obsd: Creating...
hcloud_server.fbsd: Still creating... [10s elapsed]
hcloud_server.obsd: Still creating... [10s elapsed]
hcloud_server.fbsd: Still creating... [20s elapsed]
hcloud_server.obsd: Still creating... [20s elapsed]
hcloud_server.obsd: Still creating... [30s elapsed]
hcloud_server.fbsd: Still creating... [30s elapsed]
hcloud_server.obsd: Creation complete after 36s [id=10805887]
hcloud_server.fbsd: Still creating... [40s elapsed]
hcloud_server.fbsd: Still creating... [50s elapsed]
hcloud_server.fbsd: Creation complete after 54s [id=10805888]
Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
Outputs:
server_ip_fbsd = 157.90.230.237
server_ip_obsd = 157.90.230.238
Terraform Show
$ terraform show
# hcloud_server.fbsd:
resource "hcloud_server" "fbsd" {
backups = false
datacenter = "nbg1-dc3"
id = "10805888"
image = "33811022"
ipv4_address = "157.90.230.237"
ipv6_address = "2a01:4f8:1c1c:7805::1"
ipv6_network = "2a01:4f8:1c1c:7805::/64"
keep_disk = false
location = "nbg1"
name = "fbsd"
server_type = "cx11"
status = "running"
}
# hcloud_server.obsd:
resource "hcloud_server" "obsd" {
backups = false
datacenter = "nbg1-dc3"
id = "10805887"
image = "33661841"
ipv4_address = "157.90.230.238"
ipv6_address = "2a01:4f8:1c1c:77f8::1"
ipv6_network = "2a01:4f8:1c1c:77f8::/64"
keep_disk = false
location = "nbg1"
name = "obsd"
server_type = "cx11"
status = "running"
}
Outputs:
server_ip_fbsd = "157.90.230.237"
server_ip_obsd = "157.90.230.238"
Terraform Cleanup
$ terraform destroy
hcloud_server.obsd: Refreshing state... [id=10805887]
hcloud_server.fbsd: Refreshing state... [id=10805888]
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
# hcloud_server.fbsd will be destroyed
- resource "hcloud_server" "fbsd" {
- backups = false -> null
- datacenter = "nbg1-dc3" -> null
- firewall_ids = [] -> null
- id = "10805888" -> null
- image = "33811022" -> null
- ipv4_address = "157.90.230.237" -> null
- ipv6_address = "2a01:4f8:1c1c:7805::1" -> null
- ipv6_network = "2a01:4f8:1c1c:7805::/64" -> null
- keep_disk = false -> null
- labels = {} -> null
- location = "nbg1" -> null
- name = "fbsd" -> null
- server_type = "cx11" -> null
- status = "running" -> null
}
# hcloud_server.obsd will be destroyed
- resource "hcloud_server" "obsd" {
- backups = false -> null
- datacenter = "nbg1-dc3" -> null
- firewall_ids = [] -> null
- id = "10805887" -> null
- image = "33661841" -> null
- ipv4_address = "157.90.230.238" -> null
- ipv6_address = "2a01:4f8:1c1c:77f8::1" -> null
- ipv6_network = "2a01:4f8:1c1c:77f8::/64" -> null
- keep_disk = false -> null
- labels = {} -> null
- location = "nbg1" -> null
- name = "obsd" -> null
- server_type = "cx11" -> null
- status = "running" -> null
}
Plan: 0 to add, 0 to change, 2 to destroy.
Changes to Outputs:
- server_ip_fbsd = "157.90.230.237" -> null
- server_ip_obsd = "157.90.230.238" -> null
Do you really want to destroy all resources?
Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
Enter a value: yes
hcloud_server.fbsd: Destroying... [id=10805888]
hcloud_server.obsd: Destroying... [id=10805887]
hcloud_server.fbsd: Destruction complete after 0s
hcloud_server.obsd: Destruction complete after 0s
Destroy complete! Resources: 2 destroyed.
Terraform OpenBSD & Vultr
doas pkg_add git gmake go terraform
cat << EOF
# Go, $(date)
export PATH=$PATH:$(go env GOPATH)/bin
export GOPATH=$(go env GOPATH)
EOF
mkdir -p $GOPATH/src/github.com/vultr; cd $GOPATH/src/github.com/vultr
git clone git@github.com:vultr/terraform-provider-vultr.git
cd $GOPATH/src/github.com/vultr/terraform-provider-vultr
gmake build
Any Comments ?
sha256: dd6f6fd10ab3bd3bdb1637748557ea4374a69af0239c471aae471a77fece8c85