问题描述
想在Azure上设置一个Ubuntu服务器。由于现有的镜像都不完全符合他的需求,他计划使用cloud-init来修改一个原始的Ubuntu镜像。他希望能够使用Azure Pipelines将此部署到多个环境,并且有一个部署原始实例的ARM模板。
他遇到的问题是如何将他的cloud-init脚本放入ARM模板的自定义数据参数中。由于ARM模板必须是JSON格式,似乎唯一的方法是将cloud-init脚本放在一行中。或者将cloud-init文件托管在某个地方,然后使用一些hacky的方法,例如:https://www.wintellect.com/arm-templates-and-cloud-init/。我在Azure Pipelines中使用的ARM模板任务似乎没有办法将文件内容作为参数传递。
他希望将ARM模板和cloud-init脚本作为他的私有git仓库中的单独文件。他目前正在考虑一种预处理构建步骤来将两者合并。是否有人已经这样做过,并且有代码示例?
也许我”做错了”,其他人是如何做的/最佳实践是什么?
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
根据用户提供的回答,您可以使用预处理脚本将整个cloud-init文件编码为一行的base64。以下是一个示例脚本,可以在Linux构建代理上使用:
cat cloud-init.txt | base64 -w0
这将将cloud-init.txt文件的内容编码为一行的base64字符串。其中,-w0参数将所有内容编码为一行。
如果您使用的是PowerShell,可以使用以下脚本:
$encodedContent = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($cloudInitContent))
其中,$cloudInitContent是您的cloud-init脚本内容。
使用这种方法,您可以将cloud-init脚本的内容作为ARM模板的自定义数据参数的值。
方案2
另一种方法是将cloud-init脚本作为ARM模板的参数文件的一部分。您可以将cloud-init脚本保存为一个单独的文件,并在ARM模板中引用该文件。以下是一个示例:
- 创建一个名为cloud-init.txt的文件,并将cloud-init脚本内容保存在其中。
- 创建一个名为parameters.json的文件,并将以下内容保存在其中:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"cloudInitScript": {
"value": "[base64(concat('file://', parameters('cloudInitFilePath')))]"
},
"cloudInitFilePath": {
"value": "[parameters('cloudInitFilePathValue')]"
}
}
}
- 在ARM模板中使用
parameters.json
文件中定义的参数。以下是一个示例:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"cloudInitScript": {
"type": "string"
},
"cloudInitFilePath": {
"type": "string"
}
},
"resources": [
{
"type": "Microsoft.Compute/virtualMachines",
"name": "myVM",
"apiVersion": "2020-06-01",
"location": "[resourceGroup().location]",
"properties": {
"storageProfile": {
"imageReference": {
"publisher": "Canonical",
"offer": "UbuntuServer",
"sku": "18.04-LTS",
"version": "latest"
}
},
"osProfile": {
"customData": "[parameters('cloudInitScript')]"
}
}
}
]
}
在上面的示例中,我们在ARM模板中定义了一个名为cloudInitScript
的参数,它的值是parameters.json
文件中定义的cloudInitScript
参数的值。cloudInitScript
参数的值是通过将cloudInitFilePath
参数的值与file://
前缀连接起来,并使用base64
函数进行编码得到的。
使用这种方法,您可以将cloud-init脚本作为ARM模板的参数文件的一部分,并在ARM模板中引用它。
方案3
如果您使用的是Azure CLI,您可以使用以下命令将cloud-init脚本作为ARM模板的自定义数据参数的值:
az deployment group create --resource-group <resource-group-name> --template-file <template-file> --parameters cloudInitScript="$(base64 -w0 cloud-init.txt)"
其中,<resource-group-name>
是资源组的名称,<template-file>
是ARM模板文件的路径,cloud-init.txt
是包含cloud-init脚本内容的文件。
使用这种方法,您可以直接在命令行中将cloud-init脚本作为ARM模板的自定义数据参数的值传递。
以上是几种将cloud-init与Azure ARM模板结合使用的方法,您可以根据自己的需求选择适合您的方法。希望对您有所帮助!