Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
userData.yml
file
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
Lecture notes |
Pdf slides |
|
sdiuser@martin-pc-dachboden:~$ ssh-keygen -t ed25519 ❶ Generating public/private ed25519 key pair. Enter file in which to save the key (/home/sdiuser/.ssh/id_ed25519): Created directory '/home/sdiuser/.ssh'. Enter passphrase (empty for no passphrase): ❷ Enter same passphrase again: Your identification has been saved in /home/sdiuser/.ssh/id_ed25519 ❸ Your public key has been saved in /home/sdiuser/.ssh/id_ed25519.pub ❹
Sign up at https://accounts.hetzner.com/signUp using an account name of your choice.
Optionally: Activate 2-factor authentication.
You may validate your account by ID card or similar. No payment required!
Publish your Hetzner account's username to your SDI course's group at https://learn.mi.hdm-stuttgart.de.
Upon confirmation your Hetzner project space sdi_gxy (e.g. sdi_g01 corresponding to group 1) should be accessible.
|
|
Ping your server:
The IP 91.107.232.156 serves just as a sample value irrespective of your individual actual server IP.
sdiuser:~$ ping 91.107.232.156 PING 91.107.232.156 (91.107.232.156) 56(84) bytes of data. 64 bytes from 91.107.232.156: icmp_seq=1 ttl=49 time=18.3 ms 64 bytes from 91.107.232.156 ...
Login via ssh:
ssh root@91.107.232.156
apt update
apt upgrade
reboot
root@topsy:~# apt install nginx
root@topsy:~# wget -O - 91.107.232.156 --2024-04-07 18:59:13-- http://91.107.232.156/ Connecting to 91.107.232.156:80... connected. <html> <head> <title>Welcome to nginx!</title> ...
Point your browser to http://91.107.232.156.
sdiuser:~$ telnet 91.107.232.156 80 Trying 91.107.232.156...
Why is there no answer?
sdiuser:~$ telnet 91.107.232.156 80 Trying 91.107.232.156... Connected to 91.107.232.156. Escape character is '^]'
Congrats: External Browser access is working now!
This is about $$$ MONEY $$$
Delete your server including the IPv4 address.
You may delete your firewall
“Terraform is an infrastructure as code tool that lets you build, change, and version cloud and on-prem resources safely and efficiently.”
Access you cloud project using the Hetzner GUI interface.
Go to Security
--> API
Tokens
--> Generate API token
Provide a name and hit Generate API token.
Copy the generated token's value and store it in a secure location e.g. a password manager.
The Hetzner GUI blocks future access to the token.
# Define Hetzner cloud provider
terraform {
required_providers {
hcloud = {
source = "hetznercloud/hcloud"
}
}
required_version = ">= 0.13"
}
# Configure the Hetzner Cloud API token
provider "hcloud" {
token = "your_api_token_goes_here"
}
# Create a server
resource "hcloud_server" "helloServer" {
name = "hello"
image = "debian-12"
server_type = "cx11"
}
$ terraform init
Initializing the backend...
Initializing provider plugins...
- Finding latest version of hetznercloud/hcloud...
- Installing hetznercloud/hcloud v1.46.1...
- Installed hetznercloud/hcloud v1.46.1 (signed by a HashiCorp partner, key ID 5219EACB3A77198B)
...
Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. ...
$ terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions ...
+ create
Terraform will perform the following actions:
# hcloud_server.helloServer will be created
+ resource "hcloud_server" "helloServer" {
+ allow_deprecated_images = false
+ backup_window = (known after apply)
...
}
Plan: 1 to add, 0 to change, 0 to destroy.
$ terraform apply ... Plan: 1 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.helloServer: Creating... hcloud_server.helloServer: Still creating... [10s elapsed] hcloud_server.helloServer: Creation complete after 14s [id=45822789] Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
Your server "hello" was created!
You can access your server with the following credentials:
IPv4 128.140.108.60
IPv6 2a01:4f8:1c1c:8e3a::/64
User root
Password rJ3pNvJXbqMp3XNTvFdq
You will be prompted to change your password on your first login.
To improve security, we recommend that you add an SSH key when creating a server.
Firewall blocks ssh server access:
$ ssh root@128.140.108.60
ssh: connect to host 128.140.108.60 port 22: Connection refused
Access by Vnc console login only
IP and (initial) credentials by email 😱
Solution:
resource "hcloud_firewall" "sshFw" { name = "ssh-firewall" rule { direction = "in" protocol = "tcp" port = "22" source_ips = ["0.0.0.0/0", "::/0"] } } ... resource "hcloud_server" "helloServer" { ... firewall_ids = [hcloud_firewall.sshFw.id] }
resource "hcloud_ssh_key" "loginUser" { name = "goik@hdm-stuttgart.de" public_key = file("~/.ssh/id_ed25519.pub") } ... resource "hcloud_server" "helloServer" { ... ssh_keys = [hcloud_ssh_key.loginUser.id] }
$ terraform apply # hcloud_firewall.sshFw will be created + resource "hcloud_firewall" "sshFw" { ... # hcloud_server.helloServer will be created + resource "hcloud_server" "helloServer" { ... # hcloud_ssh_key.goik will be created + resource "hcloud_ssh_key" "loginUser" { ... Plan: 3 to add, 0 to change, 0 to destroy. ... Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
See terraform output documentation:
File outputs.tf |
Result |
---|---|
|
$ terraform output
hello_datacenter = "nbg1-dc3"
hello_ip_addr = "159.69.152.37" |
$ terraform output hello_ip_addr
"159.69.152.37" |
File outputs.tf |
terraform output -json |
---|---|
|
|
Versioned file
main.tf
:
...
provider "hcloud" { token = "xdaGfz9LmwO8SWkg ... "}
...
Solution:
Declare a variable
hcloud_token
in a
variables.tf
file
Add a non-versioned file
secrets.auto.tfvars
.
Optional: Provide a versioned
secrets.auto.tfvars.template
documenting
file
Declaring variable "hcloud_token" { # See secret.auto.tfvars
nullable = false
sensitive = true
} |
Defining hcloud_token="xdaGfz9LmwO8SWkg ... " |
Using provider "hcloud" { token = var.hcloud_token } |
Example in
hcloud_token="your_api_token_goes_here" |
Cloud Stack Conference talk.
Distribution image containing pre-installed Cloud Init
Script configurable installation options
|
|
resource "hcloud_server" "web" {
name = var.server_name
...
user_data = file("userData.yml")
}
#cloud-config
packages:
- nginx
runcmd:
- systemctl enable nginx
- rm /var/www/html/*
- >
echo "I'm Nginx @ $(dig -4 TXT +short o-o.myaddr.l.google.com @ns1.google.com)
created $(date -u)" >> /var/www/html/index.html
Problem of repeated terraform
apply
:
$ ssh root@128.140.108.60
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
root@hello:~# journalctl -f May 06 04:41:20 hello cloud-init[898]: Cloud-init v. 22.4.2 finished at Mon, 06 May 2024 04:41:20 +0000. Datasource DataSourceHetzner. Up 11.78 seconds ... May 06 04:46:16 hello sshd[927]: Invalid user abc from 43.163.218.130 port 33408 May 06 04:46:17 hello sshd[927]: Received disconnect from 43.163.218.130 port 33408:11: Bye Bye [preauth] May 06 04:46:17 hello sshd[927]: Disconnected from invalid user abc 43.163.218.130 port 33408 [preauth] ... May 06 04:50:54 hello sshd[930]: fatal: Timeout before authentication for 27.128.243.225 port 59866 ... May 06 04:52:45 hello sshd[933]: Invalid user cos from 43.163.218.130 port 59776 ... May 06 04:53:04 hello sshd[935]: Invalid user admin from 194.169.175.35 port 51128 May 06 04:53:49 hello sshd[937]: User root from 43.163.218.130 not allowed because not listed in AllowUsers May 06 04:53:49 hello sshd[937]: Disconnected from invalid user root 43.163.218.130 port 50592 [preauth]
resource "hcloud_server" "helloServer" { server_type = "cx11" ... } resource "hcloud_volume" "volume01" { name = "volume1" size = 10 server_id = hcloud_server.helloServer.id automount = true format = "xfs" } |
df ... /mnt/HC_Volume_100723816 |
|
# ls /dev/disk/by-id/*100723816 /dev/disk/by-id/scsi-0HC_Volume_100723816 |
terraform apply
...
hello_ip_addr="37.27.22.189"
volume_id="100723816" |
Desired
/dev/disk/by-id/scsi-0HC_Volume_100723816
/volume01 xfs discard,nofail,defaults 0 0 |
|
Problem: Cyclic dependency helloServer <--> volume01 |
resource "hcloud_volume" "volume01" { size = 10 .... } resource "hcloud_server" "helloServer" { user_data = templatefile("tpl/userData.yml", { volume01Id = hcloud_volume.volume01.id # No cycle any more ... }) ... } resource "hcloud_volume_attachment" "main" { volume_id = hcloud_volume.volume01.id server_id = hcloud_server.helloServer.id }