Orchestrating Cloud Infrastructure with Ansible and Hetzner Cloud

The intersection of Infrastructure as Code (IaC) and high-performance cloud computing is epitomized by the integration of Ansible with Hetzner Cloud (hcloud). By leveraging the hetzner.hcloud collection, system architects and DevOps engineers can transition from manual resource provisioning to a declarative state where the entire cloud environment—comprising servers, networks, firewalls, and storage volumes—is defined in version-controlled YAML files. This approach eliminates the variance associated with manual console configuration and ensures that the infrastructure is reproducible, scalable, and idempotent. In a professional deployment, this means that running a playbook multiple times will not result in the creation of redundant servers but will instead maintain the desired state, a critical requirement for production stability and disaster recovery.

Architectural Prerequisites and Environment Setup

Before deploying resources via Ansible, a specific technical foundation must be established on the control node. The control node is the machine where Ansible is installed and from which the playbooks are executed.

Fundamental Requirements

The following components are mandatory for a functional hcloud environment:

  • Ansible Installation: A current version of Ansible must be present. While basic operations work on older versions, advanced features and specific collection updates require Ansible 2.12 or later to ensure full compatibility with the hetzner.hcloud collection.
  • Python hcloud Library: The hcloud Python library acts as the underlying SDK that Ansible uses to communicate with the Hetzner Cloud API. Without this library, the modules cannot translate YAML declarations into API calls.
  • API Token: A valid Hetzner Cloud API token is the sole mechanism for authentication. This token must be generated within the Hetzner Cloud Console under the Security > API Tokens section.

Installation Procedures

To prepare the system, the Python SDK and the Ansible collection must be installed using the following commands:

bash pip install hcloud ansible-galaxy collection install hetzner.hcloud

For users who prefer to manage the collection via source control or require the latest development features, the collection can be cloned directly into the Ansible collection path. The standard path for this is ~/.ansible/collections/ansible_collections/hetzner/hcloud. The following command facilitates this:

bash git clone [email protected]:ansible-collections/hetzner.hcloud.git ~/.ansible/collections/ansible_collections/hetzner/hcloud

This manual installation method allows developers to track the main branch for the latest features or stable-* branches for production-grade reliability, although official support for multiple versions is not provided.

The Mechanics of the hetzner.hcloud Collection

The hetzner.hcloud collection is a specialized set of modules designed to manage the lifecycle of Hetzner Cloud resources. In Ansible terminology, these are organized into roles and tasks, where a task represents a specific action, such as creating a server or attaching a volume.

Module Documentation and Discovery

Ansible provides a built-in tool for exploring the capabilities of the hcloud modules. The ansible-doc command allows users to view the full documentation, including all available arguments and examples, directly from the terminal. For instance, to examine the server module, the following command is used:

bash ansible-doc hetzner.hcloud.server

This is vital for understanding the specific parameters required for different server types, images, and locations available within the Hetzner ecosystem.

Resource Lifecycle Management

The core of the collection is the hetzner.hcloud.server module, which manages the entire lifecycle of a cloud instance. This includes the initial creation, modification of attributes, and eventual deletion of the server. The state of the resource is controlled by the state argument, typically set to present to ensure the server exists or absent to remove it.

Server Provisioning and Configuration Deep Dive

Provisioning a server involves defining a set of parameters that dictate the hardware, software, and geographic location of the instance.

Technical Specifications for Server Deployment

The following table outlines the primary parameters used within the hetzner.hcloud.server module:

Parameter Description Technical Requirement
api_token Authentication key Must be a valid Read & Write token from hcloud console
name Identifier for the server Unique string identifying the resource in the project
server_type Hardware profile Example: cpx11 or cx21 defining CPU and RAM
image OS Image Example: ubuntu-24.04 or ubuntu-22.04
location Data center region Example: ash (Ashburn) or nbg1 (Nuremberg)
state Desired existence present to create/maintain, absent to delete
ssh_keys Access credentials List of SSH keys to inject into the instance
labels Metadata tags Key-value pairs for organization (e.g., env: production)

Implementation Example: Production Web Server

To deploy a web server in the Nuremberg (nbg1) region using a secure credentials file, the following playbook structure is employed. It is highly recommended to store the API token in a separate variables file and encrypt it using ansible-vault to prevent the exposure of sensitive credentials in version control.

```yaml

# vars/hetzner_credentials.yml (Encrypted via ansible-vault)

hcloudapitoken: "your-hetzner-api-token-here"

# playbooks/create-hetzner-server.yml

  • name: Create a Hetzner Cloud server
    hosts: localhost
    gatherfacts: false
    vars
    files:

    • ../vars/hetzner_credentials.yml
      tasks:
    • name: Create web server
      hetzner.hcloud.server:
      apitoken: "{{ hcloudapitoken }}"
      name: web-01
      server
      type: cx21
      image: ubuntu-22.04
      location: nbg1
      ssh_keys:
      - deploy-key
      labels:
      role: web
      env: production
      state: present
      register: server

    • name: Show server details
      ansible.builtin.debug:
      msg: "Server {{ server.hcloudserver.name }} created at {{ server.hcloudserver.ipv4_address }}"
      ```

The use of register: server allows the playbook to capture the output of the API call, which is then used in the debug task to print the dynamically assigned IPv4 address of the new server.

Advanced SSH Key Management

Security in the cloud begins with the management of SSH keys. The hcloud_ssh_key module allows users to programmatically upload and manage public keys, ensuring that no server is ever deployed with a password-based authentication method.

Managing SSH Keys via Modules

The hcloud_ssh_key module provides several ways to identify the key being managed: by its unique ID, its name, or its fingerprint. This flexibility allows for robust automation scripts that can check for the existence of a key before attempting to upload a new one.

The parameters for the hcloud_ssh_key module are detailed below:

Argument Name Description Required
id The unique ID of the ssh_key Optional (if name is missing)
name The human-readable name of the key Optional (if id is missing)
fingerprint The unique fingerprint of the key Optional (if name/id are missing)
public_key The actual SSH public key string Required if key does not exist
state State of the key (present/absent) Optional (Default: present)
labels User-defined key-value pairs Optional

An example of declaring an SSH key is as follows:

yaml - name: Ensure the deployment key is present hetzner.hcloud.ssh_key: name: "my-ssh_key" public_key: "ssh-rsa XXXXX" state: "present"

Information Gathering with hcloud-ssh-key-info

For auditing purposes or dynamic inventory building, the hcloud-ssh-key-info module can be used to retrieve details about existing keys. Users can query specific keys using the id or name parameters to verify fingerprints or labels before proceeding with server deployments.

Integration with External Ecosystems: Cortex XSOAR

The capabilities of Ansible and Hetzner Cloud extend into the security orchestration, automation, and response (SOAR) domain through the Ansible Hetzner Cloud Pack for Cortex XSOAR. This integration allows security teams to manage cloud environments directly from a SOAR platform.

XSOAR Implementation Details

The integration is supported on Cortex XSOAR versions 6.0.0 and later. It features a self-contained Ansible engine, meaning the XSOAR server does not require a separate Ansible installation.

To configure the integration, the following parameters are mandatory:

  • API Token: Generated from the HCloud Console (Security > API Tokens) with Read & Write permissions. For versions 6.0.2 or lower, this token must be placed in the Password field while leaving the Username field empty.
  • Endpoint: The official API endpoint for the Hetzner Cloud.

The commands within this integration are idempotent, ensuring that repeated executions of a security playbook do not create duplicate infrastructure or disrupt existing services.

Specialized Tooling and Hardening Templates

Beyond basic resource creation, the community provides templates for the rapid deployment of secure environments. The "Secure Shell Networks" repository provides a specialized Ansible inventory designed for hcloud.

Linux Hardening via Ansible

This template does not stop at provisioning; it implements a series of security best practices to protect the server immediately after boot. These include:

  • Unattended Upgrades: Configuring the system to automatically install security updates to minimize the window of vulnerability.
  • SSH Hardening: Adjusting SSH configurations to disable insecure methods and enforce key-based authentication.
  • Fail2Ban: Deploying and configuring Fail2Ban to protect the server against brute-force attacks by banning IPs that show malicious signs.

To utilize this template, users must create a repository that inherits from the Secure Shell Networks template and generate a password for the Ansible Vault, which is stored in .keys/all to secure the sensitive variables.

Testing and Quality Assurance for Module Development

For those contributing to the hetzner.hcloud collection or developing custom modules, a rigorous testing framework is implemented.

Integration Testing

Testing is conducted using ansible-test. To perform integration tests, a configuration file named cloud-config-hcloud.ini must be present in the tests/integration directory. This file contains the API token required for the tests to interact with a real Hetzner environment:

ini [default] hcloud_api_token=<token>

An example of running all integration tests for the server module is:

bash ansible-test integration --color --local -vvv hetzner.hcloud.server

Release Pipeline and Experimental Features

The project uses release-please to automate the creation of Pull Requests on GitHub for new versions. When a PR is merged, the release is tagged automatically.

For experimental features, the collection follows a strict documentation and logging protocol:
- An announcement and a link to a changelog entry must be included in the release notes.
- The documentation must explicitly state that the feature is experimental and may contain breaking changes.
- An experimental warning function must be triggered when the plugin is used in a live environment.

The Python implementation for an experimental warning typically looks like this:

python product_experimental_warning = experimental_warning_function( "$PRODUCT", "$MATURITY", "https://docs.hetzner.cloud/changelog#$SLUG", ) class AnsibleProduct(AnsibleHCloud): def __init__(self, module: AnsibleModule): product_experimental_warning(module) super().__init__(module)

Conclusion

The synergy between Ansible and Hetzner Cloud transforms the process of cloud management from a manual, error-prone task into a precise science. By utilizing the hetzner.hcloud collection, operators can define their entire infrastructure—from the initial API token authentication and SSH key deployment to the provisioning of specific server types like cx21 in the nbg1 region—within a declarative framework. The ability to integrate this setup with security platforms like Cortex XSOAR and hardening templates from Secure Shell Networks ensures that the resulting infrastructure is not only scalable but also secure by default. For the modern DevOps engineer, the transition to this automated model reduces the "time to value" and provides a reliable mechanism for scaling European-based cloud compute resources while maintaining strict adherence to infrastructure-as-code principles.

Sources

  1. Secure Shell Networks: Hetzner Cloud Ansible Inventory
  2. Hetzner Community: How-to hcloud Ansible
  3. Ansible Hetzner Cloud Collection
  4. Cortex XSOAR: Ansible H Cloud Integration
  5. OneUptime: How to Use Ansible to Manage Hetzner Cloud Servers

Related Posts