Building a Custom Windows Server Image for Yandex Cloud: A Practical Guide

In late July 2026, a detailed article appeared on Habr describing the process of creating a custom Windows Server image for Yandex Cloud. The material, authored by engineers who regularly work with cloud infrastructure, provides a step-by-step approach to building a production-ready image that includes pre-installed software, security hardening, and optimised settings. This summary captures the key insights from that publication, so you can save time and avoid common mistakes.

Why Build a Custom Windows Server Image?

Standard Windows Server images provided by cloud providers often come with default configurations that may not suit your specific workload. The Habr article emphasises that building a custom image allows you to:
- Pre-install required applications and dependencies
- Apply security patches and tweak registry settings
- Reduce deployment time by eliminating manual post-install steps
- Ensure consistency across environments

The authors note that while Yandex Cloud offers a selection of Windows Server images (2019, 2022), these are generic and may contain unnecessary components or lack optimisations for high-performance computing or specific compliance requirements.

Prerequisites and Tools

According to the article, the team used the following tools and services:
- Yandex Cloud CLI – for authentication and management operations
- Packer (version 1.9+) – a popular tool for building machine images automatically
- Ansible (optional) – for configuration management inside the image
- A Yandex Cloud service account with editor role for the target folder

The authors stress the importance of using a dedicated service account rather than a personal one to avoid permission issues and facilitate CI/CD integration.

ASI Biont supports connecting to Packer via API — more details on asianbiont.com/courses

Step-by-Step Process Described in the Article

1. Prepare the Base Image

Start by choosing a source image. The authors used windows-server-2022-dc-gpu (the Datacenter edition with GPU support) because their workload required GPU compute. They fetched the image ID using the CLI:

yc compute image list --folder-id standard-images

This list includes all public images provided by Yandex Cloud. The article advises to check the product_ids field to ensure the image is not expired.

2. Create a Packer Template

A JSON (or HCL2) template defines the source, builders, and provisioners. The Habr article provides a simplified example:

{
  "builders": [
    {
      "type": "yandex",
      "service_account_key_file": "./key.json",
      "folder_id": "your-folder-id",
      "source_image_id": "fd8abc123",
      "ssh_username": "administrator",
      "use_ipv4_nat": true,
      "platform_id": "standard-v2",
      "subnet_id": "your-subnet-id"
    }
  ],
  "provisioners": [
    {
      "type": "ansible",
      "playbook_file": "playbook.yml"
    }
  ]
}

The authors highlight that ssh_username must be administrator for Windows images, and use_ipv4_nat is required if the subnet has no direct internet access.

3. Automate Windows Customisation with Ansible

Rather than running shell commands manually, the article's team used an Ansible playbook to:
- Install IIS and .NET Framework features
- Configure Windows Firewall rules
- Set time zone and regional options
- Pre-create local user accounts
- Install monitoring agents (e.g., Yandex Cloud Agent)

The playbook also runs sysprep to generalise the image before sealing:

- name: Run Sysprep
  win_command: >
    C:\Windows\System32\sysprep\sysprep.exe
    /generalize /oobe /shutdown

Important: The article warns that Sysprep must be the last step, after all other configuration, because it resets the Security ID (SID) and prepares the image for reuse.

4. Handling Licensing and Activation

Windows Server requires activation. The Habr article explains that Yandex Cloud supports two licensing models: Pay-as-you-go (includes license cost in the instance price) and Bring Your Own License (BYOL). For custom images, the team used the BYOL model with a Volume Licensing key (KMS or MAK). They configured the KMS client key using a script:

slmgr /ipk <product-key>
slmgr /skms kms.yandexcloud.net
slmgr /ato

The kms.yandexcloud.net address is Yandex Cloud's own KMS server, which works for instances inside the cloud network. This avoids the need for external internet access.

5. Testing and Validation

Before using the image in production, the authors ran a series of tests:
- Instance launch from the custom image
- Remote desktop and SSH access
- Verification of installed software and services
- Performance benchmarks (the GPU workloads ran as expected)
- Compliance scans (using OpenSCAP for Windows)

They also ensured that the instance booted without errors and that the Cloudbase-Init tool (pre-installed in the source image) executed custom scripts passed via user data.

Common Pitfalls and Solutions

The Habr article dedicates a section to issues the team encountered:

Issue Solution
Packer fails to connect via SSH Ensure port 5986 (WinRM) is open; use winrm communicator instead of ssh
Sysprep fails with error Disable Windows Defender before running Sysprep
Image too large (> 100 GB) Clean temporary files and use compressed disk format
Licensing activation fails Verify the KMS client key is correct and the instance has network access to the KMS server

Automating the Build with CI/CD

For teams that need to rebuild images regularly (e.g., after security patches), the authors integrated the Packer pipeline into a GitLab CI workflow. A simple .gitlab-ci.yml starts a Yandex Cloud runner, clones the repository, and runs packer build. The resulting image is then saved under a family name, allowing Terraform or Yandex Cloud Console to reference it easily.

build_image:
  stage: build
  script:
    - packer init .
    - packer build template.pkr.hcl
  only:
    - main

The article notes that storing the service account keys as CI/CD variables (and encrypting them) is critical security practice.

Conclusion

Building a custom Windows Server image for Yandex Cloud, as detailed in the Habr article, is a straightforward but nuanced task. By using Packer with Ansible, you can create a repeatable, version-controlled image that saves time and reduces configuration drift. The practical tips from the authors — such as using the correct KMS server, running Sysprep at the right moment, and testing thoroughly — can help you avoid hours of debugging. Whether you need a hardened image for compliance or a pre-configured environment for GPU workloads, the approach outlined in the source material provides a solid foundation.

Source

← All posts

Comments