Needs review
Project:
Cloud
Version:
8.x-dev
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
28 Feb 2026 at 14:24 UTC
Updated:
16 May 2026 at 00:25 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #3
erdinchasI'm working on it =)
Comment #5
erdinchas@orkut could you please check?
Comment #6
orkutmuratyilmaz@erdinchas, thanks for your contribution:)
Generally, the submodule looks working, but it has some phpcs, phpstan and phpunit errors. Can you solve them too?
Comment #7
erdinchasCould you please check again?
Comment #8
orkutmuratyilmazThank you @erdinchas, it works:)
Comment #9
baldwinlouie commented@erdinchas. Thank you so much for the new module. This looks like hard work to implement.
Before getting this merged, I tested it against a fresh installation of Drupal 11. I'm getting the following message when enabling
Hetzner Cloudfield.storage.cloud_config.field_api_endpoint.ymlis declared in the OpenStack submodule. If users have the OpenStack module enabled, Hetzner Cloud will encounter this installation error.One option is to rename the Hetzner Cloud's field_api_endpoint to something else.
Secondly, can you replace the
cloud/modules/cloud_service_providers/hetzner_cloud/images/hetzner_cloud.pngwith the actual Hetzner logo or image? It is currently an image of the AWS logo.Please give us your thoughts.
Comment #10
erdinchasThanks for the feedback, the issues you've raised must be solved with the latest push. Hetzner Cloud's field_api_endpoint is renamed as you've suggested. Could you please review again?
Comment #11
yas@erdinchas
Thank you for the wonderful patch. I posted my comments. Also, please add the PHPUnit tests based on CRUD. We won't merge the source code wi/o tests.
Thanks
Comment #12
baldwinlouie commented@erdinchas Thank you for the updated patch. Again, this is a lot of work and we really appreciate the patch!
I can install it now and am testing it out. I have some requests for you.
1. Please add the Hetzner Cloud provider menu to the left hand navigation. If you look at
aws_cloud.links.menu.yml, you will see a snippet that looks like this.This will dynamically add the AWS provider to the left hand navigation. See the following two images for reference. Notice the AWS links shows up in to submenus.
2. In the
Add Hetzner Cloudscreen, can you put the fields in#type=>details, similar to AWS, K8s? See screenshot:Please look at the code in
aws_cloud_form_cloud_config_aws_cloud_form_common_alter(), specifically, the functionaws_cloud_cloud_config_fieldsets(), which orders the fields for aws.You will see similar functions in K8s.
k8s_form_cloud_config_k8s_form_common_alter()k8s_cloud_config_fieldsets()3. I'd like to ask that

#type=>detailsbe used for the Hetzner entities' add/edit forms. See screenshot for an example with AWS.You can look at the Add/Edit forms in
aws_cloud/src/Form/Ec2/. All the forms are nested in'#type' => 'details',I will sign up for an account and do some additional testing.
Comment #13
erdinchasThank you both for your to the point fedbacks, appreciated!
I am just back from KubeCon and will work on your recent comments as soon as I can.
Comment #14
erdinchas@yas I have completed the revisions you've mentioned; those are ready to be reviewed.
@baldwinlouie now I'm starting to work on your suggestions :)
Comment #15
erdinchas@baldwinlouie, can you review?
Thanks to both of you for your guidance, looking forward to hear about what comes next; cheers!
Comment #16
erdinchasI just received a warning about pipeline failure, is the pipeline up to date or should I update the code?
Have a nice weekend!
Comment #17
baldwinlouie commented@erdinchas, Thank you for the updated patch. I will review it.
Don't worry about the pipeline failure. This is happening with our other Merge Requests as well.
Comment #18
baldwinlouie commented@erdinchas, I'm beginning to test the MR. The first issue I ran into is the following error:
When this happens, the module will return an error and the entire site will display a blank screen.
I've looked at the patch and traced it back to the following function.
$form['cloud_context']['#access'] = FALSE;When this is done, the `cloud_context` is not set. As a result, it is not set in the database:
As you know from building the Hetzner module, everything in the `cloud` suite is driven by the `cloud_context` value. All urls, plugin, look ups..etc...use that value.
I'm sure you're basing the
$form['cloud_context']['#access'] = FALSE;by looking at the other `provider modules` in the Cloud suite.Yes, we set it to FALSE, but we also use a custom `submit` function, and in it, we use a service to auto-generate the `cloud_context`.
For example, take a look at
k8s_form_cloud_config_k8s_add_form_submitWe set `cloud_context` to FALSE, but we also have a custom submit function to handle auto-generating the cloud_context value
Code in the K8s module that handles generating the cloud_context
Other examples include the
vmware_form_cloud_config_vmware_add_form_alterandvmware_form_cloud_config_vmware_add_form_submitfunctions.Can I ask you to update the the hetzner_cloud module to follow this convention?
Btw, is there a trial key for Hetzner cloud? I'd like to give the module a try too.
Comment #19
yas@erdinchas
Thank you for the updated patch. As for the pipeline failure, I was trying to fix composer failure at #3586634: Update a .gitlab-ci.yml file (5). Also, I fixed the following issues:
However, please note that the PHPUnit tests in the pipeline are still having errors.
Thanks
Comment #20
erdinchasI've tried my best to fix the mentioned issues, struggled a bit, but I think they're solved as far as I see.
Thanks again for your feedbacks.
Comment #21
orkutmuratyilmaz@erdinchas, sorry, but you need to pull the latest release of 8.x-dev first. then you should push your changes into this MR. I'm updating the issue's status.
Comment #22
yas@orkutmuratyilmaz
Thank you for the follow-up.
@erdinchas More specifically, please try the following:
Comment #23
erdinchasI finished merging the latest commits on 8.x and pushed it as suggested; however phpunit tests are failing due to PHP version issues.
Could you please check again?
Comment #24
yas@erdinchas
Thank you for the update. Since I've fixed the Drupal CI failure w/ the following issues, so could you please update your MR? Thanks!
Comment #25
erdinchasComment #26
baldwinlouie commented@erdinchas
Thank you for the update. I can now add a Hetzner cloud service provider without any errors.
Can I ask you to implement HetznerCloudLocalTasks.php? Please look at
K8sLocalTasks.phpandAwsCloudLocalTasks.phpfor reference.When implemented, all the Hetzner view's pages will have links to the other Hetzner entities. See following screenshot as an example.
Comment #27
erdinchasThank you for your feedback. The Hetzner Cloud entities include Servers, Volumes, Networks, Firewalls, Floating IPs, SSH Keys, Images, and Load Balancers. I have added them, ensuring the implementation style remains consistent with the existing AWS entities.
Comment #28
baldwinlouie commented@erdinchas Thank you so much for the update. The links now appear and I can click between the different Hetzner entities.
I did find a bug. Steps to reproduce.
1. Navigate to any of the Hetzner Cloud entity listing page
2. Click on "Local balancers"
3. Click "Add Load Balancer"
When doing so, I get the following exception:
Can you please take a look?
Comment #29
baldwinlouie commented@erdinchas I get a similar error when trying to add an ssh key. It seems to be happening when I try to add any of the Hetzner entities.
1. Navigate to any of the Hetzner SSH keys listing page: /clouds/hetzner_cloud/hetzner/ssh_key
2. Click "Add SSH Key"
3. Fill in the SSH key "Name" field
4. Click Save
I get the following error:
Comment #30
baldwinlouie commented@erdinchas Please take a look at one of the *CreateForm.php for AWS. The issue is because for cloud_context is not being passed to the
save()function.The {cloud_context} can be accessed as a method parameter for
buildForm(). For example, inElasticIpCreateForm.phpIf I do the same for
HetznerCloudNetworkCreateForm.phpI am able to pick up the
$cloud_context. See screenshot of my PHPStorm debug session.Comment #31
baldwinlouie commented@erdinchas I'm sorry to be asking you so many questions. I have another one.
I am looking at all the HetznerCloud*EditForms. It looks you are just making the edits in Drupal, and not making an API call to Hetzner to update the remote entities? For example, in
HetznerCloudNetworkEditForm, thesave()function looks like this:Can you confirm if the remote entity is updated?
Comment #32
erdinchasI am so glad about your questions and thanks for the detailed entries. They helped me to see a foundational problem that I've missed when making $cloud_context edits.
The exceptions on Add Load Balancer and Add SSH Key were both coming from the same place; our Create/Edit forms weren't accepting $cloud_context as a buildForm() parameter, so the entity hit save() with an empty cloud context and CloudConfigPluginManager::setCloudContext() blew up. I aligned all eight Hetzner Create/Edit forms (buildForm(..., $cloud_context = '')), set cloud_context on new entities before save.
On the last comment — yes, edits were only writing to Drupal locally and never reaching Hetzner. I have actually tested them with already existing entites, added and deleted them somehow, saw the actions took place on Hetzner console and tought it was working. Now I added updateServer/Volume/Network/Firewall/FloatingIp/SshKey/Image/LoadBalancer to HetznerCloudServiceInterface (wrapping the SDK's ->update() on each model) and wired every *EditForm::save() to push the change remotely first, aborting the local save if the API call fails.
For the Server form specifically, I followed the AWS convention: name is editable, server_type is editable but disabled unless the server is off (calling resizeServer() with an optional disk-upgrade checkbox), and image stays read-only since changing it is a rebuild action, not an update — same as how AWS treats AMI swaps.
Btw as I am unsure if you received my direct message about trial Hetzner API, I want to address it here as well. You can find it below;
"I was going to tell you that Hetzner does not make out an invoice under 5$ bill and there is no fee for account creation, so you can register and test it out freely for a while. Just do not forget to kill the servers after testing for not to get invoiced."
Comment #33
baldwinlouie commented@erdinchas Thank you so much for providing the Hetzner invoicing insight. I've created an account to do testing. It has been going great.
Thank you for fixing the Load Balancer and SSH Key issues. I'm doing more testing and am finding some additional issues.
1. Creating a volume is throwing a PHP exception. Steps to reproduce.
- Go to `Add Hetzner Cloud volume`
- Fill out the form. I filled out the following: Name="Test", Size="10", Location="fsn1", Filesystem Format="ext4"
- After clicking "Save", I get the following error:
2. Creating an SSH key does not create it on the Hetzner side. Steps to reproduce:
- Go to `Hetzner Cloud SSH Keys`
- Click `Add SSH Key`
- Fill out the Name field
- Click Save.
- Check the Hetzner console. I notice the SSH key is not created.
- I checked
HetznerCloudSshKeyCreateFormand the parentsave()method. It doesn't seem to be support creating a new SSH key.3. Creating Floating IP does not create it on the Hetzner side.
Steps to reproduce are the same as #2 above.
4. Creating a Load Balancer keeps producing a
Name field is required.validation error. Steps to reproduce:- Go to `Hetzner Cloud Load Balancers`
- Click `Add Load Balancer`
- Fill out the form. I made sure to fill out the `Name` at the top and bottom of the form.
- I get the following screenshot:
5. Creating a Server brings back the following error (Please advise if this is user error)
Steps to reproduce:

- Fill out the `Add Hetzner server` form
- Server Name: Test
- Location: Either `Auto select` or fsn1
- Server Type: cpx11
- Image: Debian 11
- Check my default SSH key
- After clicking save. I get this screenshot. I also notice the form does not repopulate with my previous entries.
Can you please take a look at these?
Thank you again in advance.
Comment #34
erdinchasHi @baldwinlouie,
Thanks a lot for the thorough review and for taking the time to test against a real Hetzner account — really appreciated. I've pushed fixes for all five issues you pointed:
1. Volume creation — the service was passing arguments to the SDK in the wrong order (size, name, …) when the SDK expects (name, size, server, location, …). Location also had to be resolved to a Location object rather than passed as a string.
2. SSH keys — the create form was missing a public_key field entirely, and save() only persisted locally. Added the field and rewired save() to call createSshKey() on the API, then re-sync.
3. Floating IPs — same root cause as SSH keys (form missing type, home_location, description; save() never hitting the API), plus the service's createFloatingIp() had its arguments in the wrong order.
4. Load Balancer name validation — the name base field had setDisplayOptions('form', …), so Drupal auto-rendered a widget that collided with the custom name field. Also discovered the SDK's LoadBalancers class doesn't expose a create() method at all, so the service now POSTs to /load_balancers directly via the HTTP client. While testing the fix I hit a follow-up "Cannot unset string offsets" fatal — that's also resolved by removing the name component from the entity form display in buildForm().
5. Server creation — made location required (the "Auto select" path was letting Hetzner pick a location that didn't support the chosen server type), added validation when the submitted server_type isn't in the catalog, and switched the error path to setRebuild(TRUE) so user input is preserved on API errors. Applied the same retention pattern to the Volume form.
Could you give it another go when you get a chance?