azure: add --generate-cloud-config for user ignition config generation - #4
Open
peytonr18 wants to merge 1 commit into
Open
azure: add --generate-cloud-config for user ignition config generation #4peytonr18 wants to merge 1 commit into
peytonr18 wants to merge 1 commit into
Conversation
Add --generate-cloud-config flag to synthesize Ignition configs from Azure IMDS metadata and OVF provisioning data.
This was referenced Dec 3, 2025
cadejacobson
reviewed
Dec 3, 2025
cadejacobson
left a comment
Collaborator
There was a problem hiding this comment.
This is awesome work! On first glance, the only improvement I see is to just add another imds error code to retry. Excited to test this out!
| ) | ||
|
|
||
| var imdsRetryCodes = []int{ | ||
| 404, |
Collaborator
There was a problem hiding this comment.
Let's add 500 to this.
cjp256
reviewed
Dec 5, 2025
| user.PasswordHash = cfgutil.StrToPtr(passwordHash) | ||
| } | ||
|
|
||
| sudoersFile := newDataFile("/etc/sudoers.d/99_wheel_nopasswd", 0440, "%wheel ALL=(ALL) NOPASSWD:ALL\n") |
There was a problem hiding this comment.
is this supposed to be unconditional?
Consider naming the file to indicate the owner, and perhaps avoid using the variables set, e.g.:
/etc/sudoers.d/50_ignition_cloud_config
cjp256
reviewed
Dec 5, 2025
| PermitRootLogin no | ||
| AllowUsers %s | ||
| `, passwordSetting, username) | ||
| sshdFile := newDataFile("/etc/ssh/sshd_config.d/10-custom.conf", 0644, sshConfig) |
There was a problem hiding this comment.
/etc/ssh/sshd_config.d/50-ignition-azure-cloud-config.conf
cjp256
reviewed
Dec 5, 2025
| Contents: types.Resource{Source: &encoded}, | ||
| }, | ||
| } | ||
| } No newline at end of file |
There was a problem hiding this comment.
check your editor for newlines at end of file
cjp256
reviewed
Dec 5, 2025
| // getRawConfig returns the config by mounting the given block device | ||
| func getRawConfig(f *resource.Fetcher, devicePath string, fstype string) ([]byte, error) { | ||
| logger := f.Logger | ||
| mnt, err := os.MkdirTemp("", "ignition-azure") |
There was a problem hiding this comment.
avoid refactoring so the diff is more concise, this can be done later
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds the ability for Azure images to generate an Ignition configuration dynamically from Azure Instance Metadata Service (IMDS) and OVF provisioning data.
Changes
GenerateCloudConfigfunction to the Azure provider that:/metadata/instance) with parametersformat=json&extended=trueovf-env.xml)Config Generation (
internal/providers/azure/azure.go):adminUsername(falls back to OVFUserName)/etc/sudoers.d/99_wheel_nopasswd- passwordless sudo for wheel group/etc/ssh/sshd_config.d/10-custom.conf- SSH hardening based on OVF settingsPassword Utilities (
internal/providers/azure/crypt.go):HashPassword()- SHA-512 crypt with random 16-char saltIsPasswordHashed()- Detects common hash prefixes (Command-line Flag (
internal/main.go):--generate-cloud-configboolean flag to the ignition binaryPlatform Interface (
internal/platform/platform.go):Providerstruct withGenerateCloudConfigfunctionUsage
The
--generate-cloud-configflag is triggered by shipping a systemd drop-in:This keeps upstream Ignition unchanged while allowing Azure to enable the feature.
Alternative: Auto-Enable for Azure Platform
If we want
--generate-cloud-configto be automatically enabled for all Azure VMs without requiring a separate drop-in, we could modify theignition-generatorto detect the platform and set the flag automatically:Benefits of this approach:
ignition.platform.idparameter (already required for Ignition)IGNITION_ARGS)GenerateCloudConfigTrade-offs:
Please offer feedback on which approach is preferred!
Additional Context: How Ignition Stages Work
Ignition runs during early boot (in the initramfs) and executes in distinct stages. Each stage is a separate invocation of the ignition binary with a different
--stageflag.Stage 1: Generator (Early Boot)
ignition-generator(a systemd generator) runs very early in boot, before any services start/run/ignition.envwithPLATFORM_IDvariableStage 2: Fetch (Config Acquisition)
ignition-fetch-offline.service(orignition-fetch.serviceif network needed) acquires the Ignition configuration.--generate-cloud-config: italls the platform'sGenerateCloudConfig()to synthesize a config from cloud metadata/run/ignition.jsonStage 3: Disks
ignition-disks.serviceruns to partition and format disks./run/ignition.jsonand then creates partitions, formats filesystems, etc.Stage 4: Mount
/run/ignition.jsonand mounts filesystems to/sysrootas specified in config.Stage 5: Files
ignition-files.serviceruns to create users, write files, configure systemd units/run/ignition.jsonand then does the following:useradd,groupadd)/etc/shadowGenerated Config Example
{ "ignition": { "version": "3.4.0" }, "passwd": { "users": [{ "name": "azureuser", "groups": ["wheel"], "homeDir": "/home/azureuser", "shell": "/bin/bash", "passwordHash": "$6$...", "sshAuthorizedKeys": ["ssh-rsa AAAA...", "ssh-ed25519 AAAA..."] }] }, "storage": { "files": [ { "path": "/etc/sudoers.d/99_wheel_nopasswd", "mode": 288, "contents": { "source": "data:,%25wheel%20ALL%3D..." } }, { "path": "/etc/ssh/sshd_config.d/10-custom.conf", "mode": 420, "contents": { "source": "data:,PasswordAuthentication%20..." } } ] } }