如何将cloud-init与Azure ARM模板结合使用

43次阅读
没有评论

问题描述

想在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模板中引用该文件。以下是一个示例:

  1. 创建一个名为cloud-init.txt的文件,并将cloud-init脚本内容保存在其中。
  2. 创建一个名为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')]"
    }
  }
}
  1. 在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模板结合使用的方法,您可以根据自己的需求选择适合您的方法。希望对您有所帮助!

正文完