This repository contains Terraform configurations to automate the provisioning of a Hetzner Cloud server with Docker CE pre-installed.
Table of Contents generated with DocToc
- Prerequisites
- Setup
- Docker CE Pre-installed
- Server Protection
- Next Steps
- Verifying Cloud-Init Installation
- Destroying Resources
- Important Notes
- Terraform (v1.11.0 or newer)
- A Hetzner Cloud account
- A Hetzner Cloud API token (with read/write permissions)
- SSH key pair
-
Clone this repository
git clone https://github.com/engineervix/provisioner.git cd provisioner -
Create your terraform.tfvars file
Copy the example file and edit it with your values:
cp terraform.tfvars.example terraform.tfvars # Edit terraform.tfvars with your text editorMake sure to:
- Add your Hetzner Cloud API token
- Specify the correct path to your Public SSH key
- Set your preferred server name and location
Security Note: By default, SSH access is not restricted by IP address since the assumption is that most users have dynamic IPs. The configuration relies on:
- SSH key-based authentication (no password access)
- Fail2ban for protection against brute force attempts
- UFW firewall as a backup security measure
-
Set up SSH Agent
This configuration uses SSH agent for authentication during provisioning, which allows the use of password-protected SSH keys:
# Start the SSH agent if not running eval "$(ssh-agent -s)" # Add your private key to the agent (you'll be prompted for the password once) ssh-add ~/.ssh/id_rsa # Verify your key was added ssh-add -l
-
Initialize Terraform
terraform init
-
Review the execution plan
terraform plan
This will show you what resources will be created without making any changes.
-
Apply the configuration
terraform apply
Type 'yes' when prompted to create the resources.
-
Connect to your new server
After the provisioning is complete, Terraform will output the IP address of your new server:
ssh -i ~/.ssh/id_rsa username@<server_ip>
Note
You might be prompted to reboot after initial login.
This configuration uses Hetzner's Docker CE app image which comes with:
- Ubuntu 24.04 as the base OS
- Docker pre-installed and configured
- Docker Compose plugin pre-installed
You can start using Docker commands immediately after server provisioning.
This configuration offers three levels of protection for your server:
-
Hetzner Cloud API Delete Protection (
delete_protection = true):- Prevents deletion via the Hetzner Cloud API
- Can be disabled through the Hetzner Cloud Console or API
- Note: This does not prevent deletion by Terraform itself, as Terraform will automatically lift this lock
-
Hetzner Cloud API Rebuild Protection (
rebuild_protection = true):- Prevents rebuilding the server via the Hetzner Cloud API
- Can be disabled through the Hetzner Cloud Console or API
-
Terraform Destroy Prevention (
prevent_terraform_destroy = false, disabled by default):- When enabled, this prevents
terraform destroyfrom deleting the resource - Strongest protection level - requires manual editing of the .tf files to remove
- Disabled by default to prevent lockout scenarios
- When enabled, this prevents
You can configure these protection levels in the terraform.tfvars file.
- Initial security hardening
- Installation of essential packages
- Configuration of unattended upgrades
After provisioning, you may want to:
- Run your Ansible playbooks for further configuration
- Deploy Docker containers for your applications
- Configure a reverse proxy such as Traefik, Caddy, NGiИX, etc.
To verify that everything was installed properly by cloud-init:
-
Check cloud-init status
cloud-init status
-
View the main cloud-init log file
sudo cat /var/log/cloud-init.log
-
Check command outputs and errors
sudo cat /var/log/cloud-init-output.log
-
Get a detailed analysis of the cloud-init run
sudo cloud-init analyze show
-
Query specific cloud-init data
sudo cloud-init query -a
If you encounter issues with oh-my-zsh, vim, or any other configuration, these logs will help identify what went wrong.
If you need to tear down the infrastructure:
terraform destroyNote
By default, this wont work unless you manually "disable protection" in your Hetzner dashboard. This is a protective measure I deliberately added to prevent accidental deletion.
Type 'yes' when prompted to destroy the resources.
- The server will be accessible via SSH immediately after provisioning
- The root password authentication is disabled by default
- Only the non-root user specified in the variables can log in via SSH with the specified key
- Make sure to keep your terraform.tfvars file secure as it contains sensitive information
- The user is automatically added to the
dockergroup and can run docker commands without sudo - This configuration uses SSH agent for provisioning, allowing the use of password-protected SSH keys