{"id":25853061,"url":"https://github.com/secshellnet/hcloud-ansible","last_synced_at":"2026-03-04T09:01:47.703Z","repository":{"id":190731262,"uuid":"683221566","full_name":"secshellnet/hcloud-ansible","owner":"secshellnet","description":"Template ansible repository for Hetzner cloud","archived":false,"fork":false,"pushed_at":"2024-06-01T16:08:44.000Z","size":2784,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-03-01T14:37:46.296Z","etag":null,"topics":["ansible-hcloud","ansible-hetzner","ansible-inventory","ansible-template","hcloud-ansible","hetzner-ansible","hetzner-cloud","iac"],"latest_commit_sha":null,"homepage":"https://hetzner.cloud","language":"Jinja","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/secshellnet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-08-25T22:36:28.000Z","updated_at":"2025-01-30T10:50:13.000Z","dependencies_parsed_at":"2023-08-26T05:07:31.504Z","dependency_job_id":"e4be9c97-7afb-4fa6-b485-cc602583928d","html_url":"https://github.com/secshellnet/hcloud-ansible","commit_stats":null,"previous_names":["secshellnet/hcloud-ansible"],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/secshellnet/hcloud-ansible","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/secshellnet%2Fhcloud-ansible","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/secshellnet%2Fhcloud-ansible/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/secshellnet%2Fhcloud-ansible/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/secshellnet%2Fhcloud-ansible/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/secshellnet","download_url":"https://codeload.github.com/secshellnet/hcloud-ansible/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/secshellnet%2Fhcloud-ansible/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30076935,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T08:01:56.766Z","status":"ssl_error","status_checked_at":"2026-03-04T08:00:42.919Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible-hcloud","ansible-hetzner","ansible-inventory","ansible-template","hcloud-ansible","hetzner-ansible","hetzner-cloud","iac"],"created_at":"2025-03-01T14:31:48.819Z","updated_at":"2026-03-04T09:01:47.683Z","avatar_url":"https://github.com/secshellnet.png","language":"Jinja","readme":"# Secure Shell Networks: [Hetzner Cloud](https://www.hetzner.com/cloud) Ansible Inventory\n\nThis repository template provides an ansible inventory to manage cloud server in \nhetzner cloud (hcloud). It performes some basic linux hardening (unattended upgrades, \nssh, fail2ban, ...) and can be extended by roles or tasks to perform whatever you need.\n\n## Getting started\nTo use this template, start by creating a repository that inherits from this template. Next \ncreate an account and a new cloud project on [hetzner.cloud](https://console.hetzner.cloud/).\nGenerate a password for the ansible vault and store it in `.keys/all`. Afterwards create a new\nansible vault with this password and add the following to it.\n```shell\n# create random password\ncat /dev/urandom | tr -dc A-Za-z0-9 | fold -w 20 | head -n 1 \u003e .keys/all\n\n# create ansible vault using predefined password\nansible-vault create group_vars/all/vault\n```\n\nAdd a random password for the worker user on the machine and the api token (see image) to the\nvault in the following format.\n![Creating an api token in the hetzner cloud console](./img/hetzner-create-api-token.png)\n\n```yaml\n---\nhcloud_api_token: \"__YOUR_API_TOKEN__\"\nworker_password: \"__RANDOM_SECRET_PASSWORD__\"\n```\n\nNext you need to extend your inventory, for example like this:\n```yaml\n---\nall:\n   hosts:\n      server1:   # default settings if no configuration given\n      server_type: cx11\n      location: hel1\n      image: ubuntu-22.04\n      enable_ipv4: false\n      enable_ipv6: true\n      server2:\n      server_type: cx21\n      location: fsn1\n      image: debian-12\n      enable_ipv4: true\n      enable_ipv6: true\n```\n\nAfter you installed the required ansible and python modules you should be able to use the inventory.\n```shell\npip3 install ansible ansible-lint\npip3 install -r requirements.txt\nansible-galaxy collection install -r requirements.yaml\nansible-galaxy role install -r requirements.yaml\n\nansible-playbook playbook.yaml\n\n# you can also limit the playbook to one of your hosts\nansible-playbook playbook.yaml --limit alpha\n\n# tags can be used to run only specific parts of a playbook\nansible-playbook playbook.yaml --list-tasks\nansible-playbook playbook.yaml --limit alpha --tags redis\n\n# to check wether the system picks up the correct variables you can run\nansible-inventory --vars --graph\n\n# make sure to lint your inventory regulary\nansible-lint\n```\n\nMake sure to create a backup of the [`.keys`](./keys/) directory. It contains the key to your\nvault and the ssh key ansible uses to connect to the cloud servers. For security reasons this\ndirectory is excluded from git operations (see [`.gitignore`](./.gitignore)), so by default it\nwill not be pushed to your git repository!\n\n## What about GitOps?\nI've tried integrating git ops, but there is one problem: the GitHub actions runner does \nnot support ipv6... So you need an ipv4 address on each vm to use git ops for now.\n\nCreate the following github actions variables and secrets in your repository and make \nsure to commit and push both your `inventory.yaml` and `group_vars/all/vault` file:\n- Variable: `ENABLE_GITOPS` to value `1`\n- Secret: `SSH_KEY` to content of [`.keys/id_ecdsa`](./keys/id_ecdsa)\n- Secret: `ANSIBLE_KEYS_ALL` to the content of [`.keys/all`](./keys/all)\n\n## Structure\n\nEven though the structure is self explaining here are some comments:\n```shell\nhcloud-ansible\n├── .github                      # github actions workflows\n│   └── workflows\n│       └── gitops.yaml\n├── .keys                        # ssh and ansible vault keys\n│   ├── all                      # key for ansible vault for group_vars all\n│   ├── id_ecdsa\n│   └── id_ecdsa.pub\n├── ansible.cfg\n├── group_vars\n│   └── all\n│       ├── defaults.yaml\n│       ├── vars.yaml            # plaintext global variables\n│       └── vault                # encrypted global variables (e. g. hetzner cloud api token)\n├── inventory.yaml\n├── playbook.yaml\n├── roles\n│   ├── ansible-role-fail2ban\n│   ├── ansible-role-nginx       # our role to install nginx with acme.sh and cf dns integration\n│   ├── ansible-role-postgresql  # role to install a postgresql database server\n│   └── ansible-role-sshd\n├── ssh\n│   └── nicof2000.pub\n├── tasks\n│   ├── linux\n│   │   ├── audit-lynis.yaml\n│   │   ├── audit-openscap.yaml\n│   │   ├── create-users.yaml\n│   │   ├── create-worker-user.yaml\n│   │   ├── setup-auditd.yaml\n│   │   ├── setup-auto-update.yaml\n│   │   ├── setup-clamav.yaml\n│   │   ├── setup-fail2ban.yaml\n│   │   ├── setup-iptables.yaml\n│   │   ├── setup-rkhunter.yaml\n│   │   └── setup-sshd.yaml\n│   └── local\n│       ├── ensure-keys-exists.yaml\n│       └── hetzner-cloud.yaml   # task to manage cloud servers and aquire information to connect\n└── templates\n    ├── auditd.rules.j2\n    ├── dnf-automatic.conf.j2\n    └── fail2ban-sshd.conf.j2\n```\n\n## [Examples](./docs/EXAMPLES.md)\n\nA full list of available system images can be aquired using the following command:\n```\ncurl -s -H \"Authorization: Bearer $TOKEN\" \\\n  \"https://api.hetzner.cloud/v1/images\" \\\n  | jq -r '.images[] | select(.type == \"system\") | .name'\n```\nTODO: For whatever reason neighter fedora nor alma linux is available in this list\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecshellnet%2Fhcloud-ansible","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsecshellnet%2Fhcloud-ansible","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsecshellnet%2Fhcloud-ansible/lists"}