Manages compute resources on Hetzner Cloud.
See requirements.txt for python library dependencies.
Given is a inventory similar as:
[web]
web-1
web-2
web-3The following variables are meant to be set in a top level group, e.g.group_vars/all.yml.
API key:
NOTE: Recommended to encrypt this token with Ansible Vault or use a lookup to your secrets management system!
hcloud__api_token: ...Ensures a private network is created:
hcloud__networks:
  - name: internal
    network: 10.10.10.0/24Ensure some firewalls and rules are created:
hcloud__firewalls:
  - name: default
    rules:
      - direction: in
        protocol: icmp
        source_ips:
          - 0.0.0.0/0
          - ::/0
      - direction: in
        protocol: tcp
        port: "22"
        source_ips:
          - 0.0.0.0/0
  - name: web
    rules:
      - direction: in
        protocol: tcp
        port: "80"
        source_ips:
          - 0.0.0.0/0
          - ::/0
      - direction: in
        protocol: tcp
        port: "443"
        source_ips:
          - 0.0.0.0/0
          - ::/0Ensure placment groups are created:
hcloud__placement_groups:
  - name: my placement group
    labels:
       project: genesisConfigure a simple load balancer and add servers as targets later (see server configs):
hcloud__loadbalancers:
  - name: my load balancer
    type: lb11
    services:
      - protocol: http
        port: 80
      - protocol: tcp
        port: 443
        destination_port: 443Configure a load balancer and use label selector hcloud feature:
hcloud__loadbalancers:
  - name: my load balancer
    type: lb11
    targets:
      - type: label_selector
        label_selector: app=public
    services:
      - protocol: http
        port: 80
        health_check:
          interval: 15
          port: 80
          timeout: 3
          retries: 3
          protocol: http
          http:
            # Single wildcard char '?' or glob wildcard '*'
            status_codes:
              - 2*
              - 3*
              - 40?
            # Optional
            path: /
            domain: www.example.com
            response: hello world
      - protocol: tcp
        port: 443
        destination_port: 443The following configs are server specific and meant to be set in a lower level group_vars or host_vars, e.g. group_vars/web.yml
Server image to use:
hcloud__server_image: debian-11Location to deploy into:
hcloud__server_location: fsn1Ensure web servers have these firewalls configured:
hcloud__server_firewalls:
  - default
  - webEnsure web servers are attached to these networks:
hcloud__server_networks:
  - name: internalEnsure web servers are in a placement group:
hcloud__server_placement_group: my placement groupAdd server to an existing loadbalancer as server target (optionally use private IP):
hcloud__server_loadbalancer_name: my load balancer
hcloud__server_loadbalancer_use_private_ip: trueEnsure web server have this type:
hcloud__server_type: cpx11User data to be executed on boot, e.g.:
hcloud__server_user_data: |
  #cloud-config
  users:
    - name: admin
      groups: users, admin
      sudo: ALL=(ALL) NOPASSWD:ALL
      shell: /bin/bash
      ssh_authorized_keys:
        - <public_ssh_key>
  packages:
    - fail2ban
  package_update: true
  package_upgrade: trueEnsure a volume is created and attached to the server:
HINT: Use the special variable
inventory_hostname_shortas prefix to easily identify which volume is attached to which server.
hcloud__server_volumes:
  - name: "{{ inventory_hostname_short }}-vol1"
    format: ext4
    size: 10A typical playbook would look like this.
---
- name: Provision Cloud servers
  hosts: all
  serial: 5
  gather_facts: false
  roles:
    - role: ngine_io.hcloud
      delegate_to: localhost
  post_tasks:
    - name: Wait for SSH access
      delegate_to: localhost
      wait_for:
        host: "{{ ansible_host }}"
        port: 22
        timeout: 60MIT
René Moser (@resmo)