{"id":21638381,"url":"https://github.com/julie-ng/azure-infra-as-code-comparison","last_synced_at":"2026-05-09T09:17:25.421Z","repository":{"id":40611619,"uuid":"388413058","full_name":"julie-ng/azure-infra-as-code-comparison","owner":"julie-ng","description":"Comparing Infrastructure as Code options for Azure. Use Case - leveraging Azure Image Builder and Shared Image Gallery to create custom Virtual Machines","archived":false,"fork":false,"pushed_at":"2021-07-23T16:50:28.000Z","size":52,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-19T01:14:02.217Z","etag":null,"topics":["arm","azure","bicep","iac","infra-as-code","pulumi","terraform"],"latest_commit_sha":null,"homepage":"","language":"Bicep","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/julie-ng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-07-22T09:56:33.000Z","updated_at":"2023-03-05T07:24:59.000Z","dependencies_parsed_at":"2022-09-23T17:11:34.358Z","dependency_job_id":null,"html_url":"https://github.com/julie-ng/azure-infra-as-code-comparison","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/julie-ng/azure-infra-as-code-comparison","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/julie-ng%2Fazure-infra-as-code-comparison","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/julie-ng%2Fazure-infra-as-code-comparison/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/julie-ng%2Fazure-infra-as-code-comparison/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/julie-ng%2Fazure-infra-as-code-comparison/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/julie-ng","download_url":"https://codeload.github.com/julie-ng/azure-infra-as-code-comparison/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/julie-ng%2Fazure-infra-as-code-comparison/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259509429,"owners_count":22868834,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["arm","azure","bicep","iac","infra-as-code","pulumi","terraform"],"created_at":"2024-11-25T04:09:23.166Z","updated_at":"2026-05-09T09:17:20.391Z","avatar_url":"https://github.com/julie-ng.png","language":"Bicep","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Azure Image Builder Test\n\nThis repo documents a _failed_ attempt to try to automate the Azure Image Builder with Infrastructure as Code (IaC) using Azure native Bicep template language.\n\n## How to Use\n\n### First - Clone Repo\n\nFirst clone this repository\n\n```bash\ngit clone https://github.com/julie-ng/azure-image-builder-test\n```\n\n### Option 1 - Azure CLI per Official Docs\n\n1. Requirement - Visual Studio Code with [Azure CLI Tools Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.azurecli) installed.\n2. Open the [`image-builder.azcli`](./image-builder.azcli) file\n3. Run each command line by line…\n\nAlternatively without Visual CLI Tools: confirm the feature is enabled and then copy Parts 1-8 into a `.sh` file and run that file.\n\n\n### Option 2 - Bicep\n\nThe multitude of shell commands in the official docs is just nasty.  In my opinion, this would be better as Infrastructure as Code (IaC). I tried 🤷‍♀️, but no luck.\n\nFirst create a resource group, optionally replacing `westeurope` with a region of your preference.\n\n```bash\naz group create --name azure-image-builder-rg --location westeurope\n```\n\nThen try the Bicep Infrastructure as Code example\n\n```bash\naz deployment group create -f ./image-builder.bicep -g azure-image-builder-rg\n```\n\n## Errors and Frustrations 😫🤬\n\nMaybe you will have better luck than me, but I had the following problems:\n\n1. Random Errors, which are formatted in nasty JSON not meant for human eyes 😵‍💫 (good luck below)\n2. What in the world is the `runOutputname` for? The official docs are self referential, i.e. is a \"run output name\" 🙄\n  \nExample Errors\n\n\u003e `{\"status\":\"Failed\",\"error\":{\"code\":\"DeploymentFailed\",\"message\":\"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.\",\"details\":[{\"code\":\"Conflict\",\"message\":\"{\\r\\n  \\\"code\\\": \\\"Conflict\\\",\\r\\n  \\\"message\\\": \\\"Update/Upgrade of image templates is currently not supported. Please change the name of the template you are submitting. If you have previously tried to submit a template and it failed to provision, you must delete it first and then resubmit. For more information, go to https://aka.ms/azvmimagebuilderts.\\\"\\r\\n}\"},{\"code\":\"BadRequest\",\"message\":\"{\\r\\n  \\\"error\\\": {\\r\\n    \\\"code\\\": \\\"RoleAssignmentUpdateNotPermitted\\\",\\r\\n    \\\"message\\\": \\\"Tenant ID, application ID, principal ID, and scope are not allowed to be updated.\\\"\\r\\n  }\\r\\n}\"}]}}`\n\nAnd another one\n\n\u003e `{\"status\":\"Failed\",\"error\":{\"code\":\"DeploymentFailed\",\"message\":\"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.\",\"details\":[{\"code\":\"Conflict\",\"message\":\"{\\r\\n  \\\"code\\\": \\\"Conflict\\\",\\r\\n  \\\"message\\\": \\\"Update/Upgrade of image templates is currently not supported. Please change the name of the template you are submitting. If you have previously tried to submit a template and it failed to provision, you must delete it first and then resubmit. For more information, go to https://aka.ms/azvmimagebuilderts.\\\"\\r\\n}\"},{\"code\":\"BadRequest\",\"message\":\"{\\r\\n  \\\"error\\\": {\\r\\n    \\\"code\\\": \\\"RoleAssignmentUpdateNotPermitted\\\",\\r\\n    \\\"message\\\": \\\"Tenant ID, application ID, principal ID, and scope are not allowed to be updated.\\\"\\r\\n  }\\r\\n}\"}]}}`\n\n### Why are the error outputs not formatted?\n\nI thought about throwing the commands into a node.js file just so I can format the output for easier debugging. \n\nBut this is not possible because of the nested JSON output. For example `JSON.parse()` chokes on the `message:` key because it contains more JSON as string.\n\n\u003e `\"message\": \"{\\r\\n  \\\"code\\\": \\\"Conflict\\\",\\r\\n  \\\"message\\\": \\\"Update/Upgrade of image templates is currently not supported. Please change the name of the template you are submitting. If you have previously tried to submit a template and it failed to provision, you must delete it first and then resubmit. For more information, go to https://aka.ms/azvmimagebuilderts.\\\"\\r\\n}\"\n`\n\nAfter trying to grab the nested bits via regular expressions and to parse first, I gave up. \n\n## Use Case\n\nWhy did I even try this? Image a customer has multiple workloads, including containers in Kubernetes. Certain components however must run in custom Virtual images.\n\n#### Challenge - VHDs will be deprecated\n\nCustomer is using HashiCorp Packer to prepare Virtual Machine image. But it displays a [warning message from that Azure Virtual Hard disks will be deprecated (eventually)](https://www.packer.io/docs/builders/azure/arm#azure-arm-builder-specific-options).\n\nIn the official Azure Doc [How to use Packer to create Linux virtual machine images in Azure](https://docs.microsoft.com/azure/virtual-machines/linux/build-image-with-packer) it recommends:\n\u003e Azure now has a service, Azure Image Builder, for defining and creating your own custom images. Azure Image Builder is built on Packer, so you can even use your existing Packer shell provisioner scripts with it. To get started with Azure Image Builder, see [Create a Linux VM with Azure Image Builder](https://docs.microsoft.com/azure/virtual-machines/linux/image-builder).\n\n\n### Using Azure Image Builder\n\nThe [Create a Linux VM with Azure Image Builder](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/image-builder) link has a lot of complex code, for example:\n\n```\ncurl https://raw.githubusercontent.com/Azure/azvmimagebuilder/master/quickquickstarts/1_Creating_a_Custom_Linux_Shared_Image_Gallery_Image/helloImageTemplateforSIG.json -o helloImageTemplateforSIG.json\nsed -i -e \"s/\u003csubscriptionID\u003e/$subscriptionID/g\" helloImageTemplateforSIG.json\nsed -i -e \"s/\u003crgName\u003e/$sigResourceGroup/g\" helloImageTemplateforSIG.json\nsed -i -e \"s/\u003cimageDefName\u003e/$imageDefName/g\" helloImageTemplateforSIG.json\nsed -i -e \"s/\u003csharedImageGalName\u003e/$sigName/g\" helloImageTemplateforSIG.json\nsed -i -e \"s/\u003cregion1\u003e/$location/g\" helloImageTemplateforSIG.json\nsed -i -e \"s/\u003cregion2\u003e/$additionalregion/g\" helloImageTemplateforSIG.json\nsed -i -e \"s/\u003crunOutputName\u003e/$runOutputName/g\" helloImageTemplateforSIG.json\nsed -i -e \"s%\u003cimgBuilderId\u003e%$imgBuilderId%g\" helloImageTemplateforSIG.json\n```\n\nIn my opinion this is **bad practice** and should instead be done using Infrastructure as Code templates, ideally in a single command, for example:\n\n```bash\naz deployment group create -f ./image-builder.bicep -g azure-image-builder-rg\n```\n\n\n## Misc.\n\n### Packer Message about VHD deprecation\n\nExample output with my test use case to create a build agent.\n\n```bash\n$ packer build azure-devops-agent.pkr.hcl\nazure-arm.ubuntu-agent: output will be in this color.\n\n==\u003e azure-arm.ubuntu-agent: Running builder ...\n==\u003e azure-arm.ubuntu-agent: Getting tokens using client secret\n==\u003e azure-arm.ubuntu-agent: Getting tokens using client secret\n    azure-arm.ubuntu-agent: Creating Azure Resource Manager (ARM) client ...\n==\u003e azure-arm.ubuntu-agent: Warning: You are using Azure Packer Builder to create VHDs which is being deprecated, consider using Managed Images. Learn more https://www.packer.io/docs/builders/azure/arm#azure-arm-builder-specific-options\n```\n\n## References\n\n- [Create a Linux image and distribute it to a Shared Image Gallery by using Azure CLI](https://docs.microsoft.com/azure/virtual-machines/linux/image-builder)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjulie-ng%2Fazure-infra-as-code-comparison","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjulie-ng%2Fazure-infra-as-code-comparison","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjulie-ng%2Fazure-infra-as-code-comparison/lists"}