A Pulumi provider for uploading custom images to Hetzner Cloud using hcloud-upload-image.
This provider allows you to upload disk images to Hetzner Cloud and create snapshots that can be used to create servers.
To build the provider locally:
make build
For local testing, you can install the plugin directly:
make install-plugin
To generate SDKs for all supported languages (automatically runs in CI on PRs):
make gen-sdk
You can also generate SDKs for specific languages:
- TypeScript:
make gen-sdk-typescript
- Python:
make gen-sdk-python
- Go:
make gen-sdk-go
- C#:
make gen-sdk-csharp
- Java:
make gen-sdk-java
To create a new version, update the version in the version
file. The current version format is semantic versioning (e.g., v0.0.1
).
package main
import (
"errors"
"fmt"
"time"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"github.com/exivity/pulumi-hcloud-upload-image/sdk/go/pulumi-hcloud-upload-image/hcloudimages"
)
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
snapshot, err := hcloudimages.NewUploadedImage(ctx, "my-image", &hcloudimages.UploadedImageArgs{
Description: pulumi.Sprintf("Custom image - %s", time.Now().Format(time.RFC3339)),
HcloudToken: pulumi.String("your-hetzner-token"),
Architecture: pulumi.String("x86"),
ImageUrl: pulumi.String("https://example.com/my-image.raw.xz"),
ImageCompression: pulumi.StringPtr("xz"),
ServerType: pulumi.String("cx11"),
Labels: pulumi.StringMap{
"environment": pulumi.String("production"),
"stack": pulumi.String(ctx.Stack()),
"project": pulumi.String(ctx.Project()),
},
}, pulumi.IgnoreChanges([]string{"description"}))
if err != nil {
return err
}
ctx.Export("imageId", snapshot.ImageId)
ctx.Export("imageName", snapshot.ImageName)
return nil
})
}
import * as pulumi from "@pulumi/pulumi";
import * as hcloud from "@exivity/pulumi-hcloud-upload-image";
const snapshot = new hcloud.hcloudimages.UploadedImage("my-image", {
description: `Custom image - ${new Date().toISOString()}`,
hcloudToken: "your-hetzner-token",
architecture: "x86",
imageUrl: "https://example.com/my-image.raw.xz",
imageCompression: "xz",
serverType: "cx11",
labels: {
environment: "production",
stack: pulumi.getStack(),
project: pulumi.getProject(),
},
}, {
ignoreChanges: ["description"],
});
export const imageId = snapshot.imageId;
export const imageName = snapshot.imageName;
import pulumi
import pulumi_hcloud_upload_image as hcloud
snapshot = hcloud.hcloudimages.UploadedImage("my-image",
description=f"Custom image - {pulumi.get_project()}-{pulumi.get_stack()}",
hcloud_token="your-hetzner-token",
architecture="x86",
image_url="https://example.com/my-image.raw.xz",
image_compression="xz",
server_type="cx11",
labels={
"environment": "production",
"stack": pulumi.get_stack(),
"project": pulumi.get_project(),
},
opts=pulumi.ResourceOptions(ignore_changes=["description"])
)
pulumi.export("image_id", snapshot.image_id)
pulumi.export("image_name", snapshot.image_name)
using System.Collections.Generic;
using Pulumi;
using HcloudUploadImage = HcloudUploadImage.HcloudUploadImage;
return await Deployment.RunAsync(() =>
{
var snapshot = new HcloudUploadImage.Hcloudimages.UploadedImage("my-image", new()
{
Description = $"Custom image - {Deployment.Instance.ProjectName}-{Deployment.Instance.StackName}",
HcloudToken = "your-hetzner-token",
Architecture = "x86",
ImageUrl = "https://example.com/my-image.raw.xz",
ImageCompression = "xz",
ServerType = "cx11",
Labels = new Dictionary<string, string>
{
["environment"] = "production",
["stack"] = Deployment.Instance.StackName,
["project"] = Deployment.Instance.ProjectName,
},
}, new CustomResourceOptions
{
IgnoreChanges = { "description" },
});
return new Dictionary<string, object?>
{
["imageId"] = snapshot.ImageId,
["imageName"] = snapshot.ImageName,
};
});
architecture
(string): The architecture of the image. Supported values: 'x86', 'arm'hcloudToken
(string): The Hetzner Cloud API token
description
(string): Optional description for the resulting imageimageCompression
(string): The compression format of the image. Supported values: 'none', 'bz2', 'xz'. Defaults to 'none'imageFormat
(string): The format of the image. Supported values: 'raw', 'qcow2'. Defaults to 'raw'imageSize
(number): Optional size validation for the image in bytesimageUrl
(string): The URL to download the image from. Must be publicly accessiblelabels
(map): Labels to add to the resulting image. These can be used to filter images laterserverType
(string): Optional server type to use for the temporary server. If not specified, a default will be chosen based on architecture
created
(string): The creation timestamp of the imagediskSize
(number): The disk size of the image in GBimageId
(number): The ID of the created Hetzner Cloud imageimageName
(string): The name of the created imageosFlavor
(string): The OS flavor of the imageosVersion
(string): The OS version of the imagestatus
(string): The current status of the imagetype
(string): The type of the image
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests and ensure SDK generation works:
make gen-sdk
- Submit a pull request
This project is licensed under the MIT License. See the LICENSE file for details.